Lets do a short introduction to what we’re working with here.

Target Variable

#original Siebert Data
aei <- read.csv2("/Volumes/RachelExternal/Thesis/Data/SiebertData/HID_v10/Country_tenyear_ha.csv")
aei <- as.data.frame(aei)

#rename the cols so that I can use them as number
colnames(aei) <- c("country", "ISO", "ID", "1900", "1910","1920","1930","1940","1950","1960","1970","1980","1985","1990","1995","2000","2005")

#tidying data to long format
aei <- pivot_longer(aei,cols = 4:17, names_to = "year", values_to = "aei_ha")
aei$aei_ha <- removePunctuation(aei$aei_ha)
aei$year <- as.numeric(aei$year)
aei$aei_ha <- as.numeric(aei$aei_ha)
aei$ISO <- as.factor(aei$ISO)
aei$country <- as.factor(aei$country)
#subset the data so that its from the year 1960
aei <- aei %>% subset(year >= 1960)

#make a new col for year count
aei$yearcount <- (aei$year - 1960)

#remove data for the total global irrigated area
globeaei <- subset(aei, country == "WORLD")
aei= aei[!aei$country == "WORLD",]

str(aei)
tibble [1,848 × 6] (S3: tbl_df/tbl/data.frame)
 $ country  : Factor w/ 232 levels "Afghanistan",..: 1 1 1 1 1 1 1 1 2 2 ...
 $ ISO      : Factor w/ 232 levels "","ABW","AFG",..: 3 3 3 3 3 3 3 3 6 6 ...
 $ ID       : int [1:1848] 2 2 2 2 2 2 2 2 6 6 ...
 $ year     : num [1:1848] 1960 1970 1980 1985 1990 ...
 $ aei_ha   : num [1:1848] 2404990 2408168 2518178 2594394 2903569 ...
 $ yearcount: num [1:1848] 0 10 20 25 30 35 40 45 0 10 ...

Added to this to be able to calculate the % of land irrigated per country we need the country area. This data is taken from Worldbank.

#import the data set with total country area, this comes from the Worldbank
countryarea <- read.csv2("/Volumes/RachelExternal/Thesis/Data/LandArea/LandArea.csv")

#removing extra cols
countryarea <- countryarea[-c(265:270), ]
countryarea <- countryarea[, -c(1, 3:4)]

#fix the col names (in the two days since i found this little for loop I learned how to do this faster!)
for ( col in 2:ncol(countryarea)){
    colnames(countryarea)[col] <-  sub("X", "", colnames(countryarea)[col])
}
remove(col)

#making long data
countryarea <- 
  countryarea %>%  
  pivot_longer(!Country.Code, names_to = "year", values_to = "area_km") %>% 
  rename(ISO = Country.Code)

#fixing variable types
countryarea$ISO <- as.factor(countryarea$ISO)
countryarea$year <- as.numeric(countryarea$year)
str(countryarea)
tibble [16,104 × 3] (S3: tbl_df/tbl/data.frame)
 $ ISO    : Factor w/ 264 levels "ABW","AFG","AGO",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ year   : num [1:16104] 1960 1961 1962 1963 1964 ...
 $ area_km: num [1:16104] NA 180 180 180 180 180 180 180 180 180 ...

For some reason, the data from Worldbank on each countries area only starts in 1961. For this analysis, 1960 is needed. Country area from 1961 will be substituted for 1960, with the assumption that country area doesn’t change drastically in one year (it doesn’t).

head(subset(countryarea, c(year == 1960 | year == 1961))) 

#fixing 1960
countryarea <-
  countryarea %>% 
  group_by(ISO) %>% 
  fill(area_km, .direction = "up") %>% 
  ungroup()

Merge the country area with the AEI df here.

#combine these data sets
aei <- aei %>% merge(y = countryarea, by.x = c("ISO", "year"), all.x = TRUE)

rm(countryarea)
head(aei)

Some countries also have no area value. I’ll go through and see if any of the countries with missing area values have non zero AEI_ha. If so, I’ll replace them, as they didn’t come through with the WorldBank data set but are online. Copying and pasting from various sources should be fine.

#checking for countries with NA values in their area_km col
#looking primarily for countries that have non 0 AEI_ha
aei[is.na(aei$area_km),]
                
#fixing counties with no area
aei$area_km[which(aei$ISO == "GUF")] <- 83534 #French Guiana from Britannica
aei$area_km[which(aei$ISO == "GLP")] <- 1630 #Guadeloupe from Britannica 
aei$area_km[which(aei$ISO == "MTQ")] <- 1128 # Martinique from Britannica
aei$area_km[which(aei$ISO == "REU")] <- 2512 #Reunion from Britannica
aei$area_km[which(aei$ISO == "SMK")] <- 13812 + 10905 + 77589 #Montenegro + Kosovo + Serbia from Britannica
aei$area_km[which(aei$ISO == "TWN")] <- 35980 #Taiwan from CIA.gov
aei$area_km[which(aei$ISO == "SDN")] <- 1882000 #Sudan from UNDP

Now, transform the AEI_ha to \(km^2\) and divide to get the % of total country area that is equipped for irrigation. There are still some countries that have 0 AEI_ha and no area_km value. I think I will assign the irrfrac/perc 0 to those countries, but lets wait a little while to do that, most are islands.

aei <- aei %>% mutate(irrperc = ((aei_ha/100)/area_km)*100, irrfrac = ((aei_ha/100)/area_km))

Here is a quick histogram of the target variable. A lot of 0s.

hist(aei$irrperc, breaks = 200)


Chosen Predictor Variables

According to the FAO (Walker 1989), the choice of which irrigation, and by proxy whether to irrigate or not, comes from six factors. The predictor that will be used for this analysis are listed below:

All variables will be scaled or centered.

First, the ISO codes and Regions to be able to hold some structure.

#the ISO codes and regional data from Gapminder
iso <- read.csv2("/Volumes/RachelExternal/Thesis/Thesis/Data/GAPminder_ISOcodes.csv")
iso <- iso[, -c(2,7,10,12,13)] #removing extra info

#renaming some cols
iso <- 
  iso %>% 
  rename(ISO = GEO, country = name)

#fixing the variable types
iso$ISO <- as.factor(iso$ISO)
iso$country <- as.factor(iso$country)
iso$four_regions <- as.factor(iso$four_regions)
iso$eight_regions <- as.factor(iso$eight_regions)
iso$six_regions <- as.factor(iso$six_regions)
iso$six_regions <- as.factor(iso$six_regions)
iso$World.bank.region <- as.factor(iso$World.bank.region)
str(iso)
'data.frame':   197 obs. of  8 variables:
 $ ISO              : Factor w/ 197 levels "AFG","AGO","ALB",..: 1 3 50 4 2 8 6 7 9 10 ...
 $ country          : Factor w/ 197 levels "Afghanistan",..: 1 2 3 4 5 6 7 8 9 10 ...
 $ four_regions     : Factor w/ 4 levels "africa","americas",..: 3 4 1 4 1 2 2 4 3 4 ...
 $ eight_regions    : Factor w/ 8 levels "africa_north",..: 5 7 1 8 2 3 4 7 6 8 ...
 $ six_regions      : Factor w/ 6 levels "america","east_asia_pacific",..: 5 3 4 3 6 1 1 3 2 3 ...
 $ Latitude         : num  33 41 28 42.5 -12.5 ...
 $ Longitude        : num  66 20 3 1.52 18.5 ...
 $ World.bank.region: Factor w/ 8 levels "","East Asia & Pacific",..: 7 3 5 3 8 4 4 3 2 3 ...
#past me helping future me
#fixing Macedonia, FYR to North Macedonia
iso$country <- as.character(iso$country)
iso[iso == "Macedonia, FYR"] <- "North Macedonia"
iso$country <- as.factor(iso$country)

Cool, we have multiple regions here that we could use in the future for some multilevel business. Also, latitude and longitude is here, which we can also try later. Obviously these lat and lon measurements will mean nothing for a country like China or the USA, but they are nice to have.

Income

Income data is coming from Gapminder, as they have put real effort in to filling all the gaps in income and population for the last 150 years. Income is in terms of the 2011 USD and is inflation adjusted.

#income here is 2011 usd 
income <- read.csv("/Volumes/RachelExternal/Thesis/Thesis/Data/Gapminder_income_per_person_gdppercapita_ppp_inflation_adjusted.csv")
income <- income[, c(1, 162:207)] #removing extra years

#making long data
income <- 
  income %>%  
  pivot_longer(!country, names_to = "year", values_to = "income") 

#still have the xs there
income$year <- str_remove_all(income$year, "[X]")
#transformation of the variable types
income$year <- as.numeric(income$year)
income$country <- as.factor(income$country)

#log and standardize
income$log_income <- log(income$income)
income <- income %>% 
  mutate(log_income_std = log_income / mean(log_income))

#a summary
summary(income)
                country          year          income      
 Afghanistan        :  46   Min.   :1960   Min.   :   312  
 Albania            :  46   1st Qu.:1971   1st Qu.:  2250  
 Algeria            :  46   Median :1982   Median :  5290  
 Andorra            :  46   Mean   :1982   Mean   : 11344  
 Angola             :  46   3rd Qu.:1994   3rd Qu.: 13575  
 Antigua and Barbuda:  46   Max.   :2005   Max.   :179000  
 (Other)            :8602                                  
   log_income     log_income_std  
 Min.   : 5.743   Min.   :0.6651  
 1st Qu.: 7.719   1st Qu.:0.8939  
 Median : 8.574   Median :0.9929  
 Mean   : 8.635   Mean   :1.0000  
 3rd Qu.: 9.516   3rd Qu.:1.1020  
 Max.   :12.095   Max.   :1.4007  
                                  
#past me helping future me again
#fixing Eswatini to Swaziland (even though Eswatini is the correct name)
income$country <- as.character(income$country)
income[income == "Eswatini"] <- "Swaziland"
income$country <- as.factor(income$country)

Logging and standardizing is necessary here. Again, the argument is that wealth begets wealth, so income is logarithmic. From there just center the mean at 0 with a stdev of 1 for standardization.

Population

Population data is also taken from Gapminder. The same process of logging and standardizing will be carried out here.

#population data also taken from Gapminder
population <- read.csv("/Volumes/RachelExternal/Thesis/Thesis/Data/Gapminder_population_total.csv")

#removing extra years
population <- population[, c(1, 162:207)] 
#making longer data
population <- 
  population %>%  
  pivot_longer(!country, names_to = "year", values_to = "population") 

#removing the Xs from the year strings
population$year <- str_remove_all(population$year, "[X]")

#fixing variable types
population$country <- as.factor(population$country)
population$year <- as.numeric(population$year)

#log and standardize, same argument as income: population begets population
population$log_pop <- log(population$population)
population <- population %>% 
  mutate(log_pop_std = log_pop / mean(log_pop))

summary(population)
                country          year     
 Afghanistan        :  46   Min.   :1960  
 Albania            :  46   1st Qu.:1971  
 Algeria            :  46   Median :1982  
 Andorra            :  46   Mean   :1982  
 Angola             :  46   3rd Qu.:1994  
 Antigua and Barbuda:  46   Max.   :2005  
 (Other)            :8694                 
   population           log_pop        log_pop_std    
 Min.   :6.450e+02   Min.   : 6.469   Min.   :0.4316  
 1st Qu.:9.045e+05   1st Qu.:13.715   1st Qu.:0.9151  
 Median :4.545e+06   Median :15.330   Median :1.0228  
 Mean   :2.404e+07   Mean   :14.988   Mean   :1.0000  
 3rd Qu.:1.320e+07   3rd Qu.:16.396   3rd Qu.:1.0939  
 Max.   :1.330e+09   Max.   :21.008   Max.   :1.4017  
                                                      
#annnd again...
#fixing Eswatini to Swaziland (even though Eswatini is the correct name)
population$country <- as.character(population$country)
population[population == "Eswatini"] <- "Swaziland"
population$country <- as.factor(population$country)

So some issues arise here with the fact that we have different country data for each dataframe. Sometimes the names are capitalized, other times there are spaces instead of underscores. By using anti_join() I can see what won’t be joined. Also this goes both ways, anti_join() returns rows of x that do not have a match in y.

isopop <- anti_join(iso, population, by = "country")
summary(isopop)
      ISO                country    four_regions
 HKG    :1   Hong Kong, China:1   africa  :0    
 TWN    :1   Taiwan          :1   americas:0    
 AFG    :0   Afghanistan     :0   asia    :2    
 AGO    :0   Albania         :0   europe  :0    
 ALB    :0   Algeria         :0                 
 AND    :0   Andorra         :0                 
 (Other):0   (Other)         :0                 
            eight_regions                   six_regions
 east_asia_pacific :2     america                 :0   
 africa_north      :0     east_asia_pacific       :2   
 africa_sub_saharan:0     europe_central_asia     :0   
 america_north     :0     middle_east_north_africa:0   
 america_south     :0     south_asia              :0   
 asia_west         :0     sub_saharan_africa      :0   
 (Other)           :0                                  
    Latitude       Longitude    
 Min.   :22.29   Min.   :114.2  
 1st Qu.:22.71   1st Qu.:115.9  
 Median :23.14   Median :117.6  
 Mean   :23.14   Mean   :117.6  
 3rd Qu.:23.57   3rd Qu.:119.3  
 Max.   :24.00   Max.   :121.0  
                                
                  World.bank.region
 East Asia & Pacific       :2      
                           :0      
 Europe & Central Asia     :0      
 Latin America & Caribbean :0      
 Middle East & North Africa:0      
 North America             :0      
 (Other)                   :0      
popiso <- anti_join(population, iso, by = "country")
summary(popiso)
                country       year       population 
 Afghanistan        :0   Min.   : NA   Min.   : NA  
 Albania            :0   1st Qu.: NA   1st Qu.: NA  
 Algeria            :0   Median : NA   Median : NA  
 Andorra            :0   Mean   :NaN   Mean   :NaN  
 Angola             :0   3rd Qu.: NA   3rd Qu.: NA  
 Antigua and Barbuda:0   Max.   : NA   Max.   : NA  
 (Other)            :0                              
    log_pop     log_pop_std 
 Min.   : NA   Min.   : NA  
 1st Qu.: NA   1st Qu.: NA  
 Median : NA   Median : NA  
 Mean   :NaN   Mean   :NaN  
 3rd Qu.: NA   3rd Qu.: NA  
 Max.   : NA   Max.   : NA  
                            

Went back up and solved the issue of North Macedonia and Swaziland. There are still issues with Hong Kong and Taiwan as they are part of China. ISO has data for Hong Kong and Taiwan that population does not have. I wont include them in the HTML but they are in the code.

Alright, so I will left join ISO and population then again with income? Not sure that this will solve my problem, but lets try it.

#remove all these rando tables
rm(popinc, inciso, incpop, popiso, isoinc, isopop)

#
iso <- left_join(iso, population, by = "country")
iso <- left_join(iso, income, by = c("country", "year"))

# alright 197 countries! whoop!
str(iso)
'data.frame':   8972 obs. of  15 variables:
 $ ISO              : Factor w/ 197 levels "AFG","AGO","ALB",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ country          : Factor w/ 197 levels "Afghanistan",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ four_regions     : Factor w/ 4 levels "africa","americas",..: 3 3 3 3 3 3 3 3 3 3 ...
 $ eight_regions    : Factor w/ 8 levels "africa_north",..: 5 5 5 5 5 5 5 5 5 5 ...
 $ six_regions      : Factor w/ 6 levels "america","east_asia_pacific",..: 5 5 5 5 5 5 5 5 5 5 ...
 $ Latitude         : num  33 33 33 33 33 33 33 33 33 33 ...
 $ Longitude        : num  66 66 66 66 66 66 66 66 66 66 ...
 $ World.bank.region: Factor w/ 8 levels "","East Asia & Pacific",..: 7 7 7 7 7 7 7 7 7 7 ...
 $ year             : num  1960 1961 1962 1963 1964 ...
 $ population       : int  9000000 9170000 9350000 9540000 9740000 9960000 10200000 10400000 10600000 10900000 ...
 $ log_pop          : num  16 16 16.1 16.1 16.1 ...
 $ log_pop_std      : num  1.07 1.07 1.07 1.07 1.07 ...
 $ income           : int  2740 2700 2680 2670 2650 2640 2600 2600 2620 2590 ...
 $ log_income       : num  7.92 7.9 7.89 7.89 7.88 ...
 $ log_income_std   : num  0.917 0.915 0.914 0.914 0.913 ...
rm(income, population)

Now, join ISO to AEI with a merge (cause in this case the dynamics of merge are clearer for me). Hoping to preserve all data!

aei <- merge(aei, iso, by = c("ISO","country", "year"), all.x = TRUE)
rm(iso)
str(aei) 
'data.frame':   1848 obs. of  21 variables:
 $ ISO              : Factor w/ 232 levels "","ABW","AFG",..: 2 2 2 2 2 2 2 2 3 3 ...
 $ country          : Factor w/ 232 levels "Afghanistan",..: 12 12 12 12 12 12 12 12 1 1 ...
 $ year             : num  1960 1970 1980 1985 1990 ...
 $ ID               : int  1 1 1 1 1 1 1 1 2 2 ...
 $ aei_ha           : num  0 0 0 0 0 ...
 $ yearcount        : num  0 10 20 25 30 35 40 45 0 10 ...
 $ area_km          : num  180 180 180 180 180 ...
 $ irrperc          : num  0 0 0 0 0 ...
 $ irrfrac          : num  0 0 0 0 0 ...
 $ four_regions     : Factor w/ 4 levels "africa","americas",..: NA NA NA NA NA NA NA NA 3 3 ...
 $ eight_regions    : Factor w/ 8 levels "africa_north",..: NA NA NA NA NA NA NA NA 5 5 ...
 $ six_regions      : Factor w/ 6 levels "america","east_asia_pacific",..: NA NA NA NA NA NA NA NA 5 5 ...
 $ Latitude         : num  NA NA NA NA NA NA NA NA 33 33 ...
 $ Longitude        : num  NA NA NA NA NA NA NA NA 66 66 ...
 $ World.bank.region: Factor w/ 8 levels "","East Asia & Pacific",..: NA NA NA NA NA NA NA NA 7 7 ...
 $ population       : int  NA NA NA NA NA NA NA NA 9000000 11200000 ...
 $ log_pop          : num  NA NA NA NA NA ...
 $ log_pop_std      : num  NA NA NA NA NA ...
 $ income           : int  NA NA NA NA NA NA NA NA 2740 2570 ...
 $ log_income       : num  NA NA NA NA NA ...
 $ log_income_std   : num  NA NA NA NA NA ...

Solved the issue, 232 factors for both countries and ISO, meaning that we have been using the original AEI file from Siebert as the main data frame to join to. Good. This is the data that needs to be maintained, NAs can pop up in other cols but not irrigated area.

But I still would like total GDP for later so lets transform using population.

aei$income <- as.numeric(aei$income) 

#mutating for total GDP and log GDP
aei <-
  aei %>%
  mutate(GDPtot = income*population) %>%
  mutate(log_gdp_tot = log(GDPtot)) 

#creating the df to standardize without the NAs
aei2 <-
  aei %>% 
  select(ISO, year, log_gdp_tot) %>%
  na.omit() %>% 
  mutate(log_gdp_tot_std = log_gdp_tot/mean(log_gdp_tot)) %>% 
  select(ISO, year, log_gdp_tot_std)

#now rejoin!
aei <- 
  left_join(aei, aei2, by = c("ISO", "year"))

str(aei)
'data.frame':   1848 obs. of  24 variables:
 $ ISO              : Factor w/ 232 levels "","ABW","AFG",..: 2 2 2 2 2 2 2 2 3 3 ...
 $ country          : Factor w/ 232 levels "Afghanistan",..: 12 12 12 12 12 12 12 12 1 1 ...
 $ year             : num  1960 1970 1980 1985 1990 ...
 $ ID               : int  1 1 1 1 1 1 1 1 2 2 ...
 $ aei_ha           : num  0 0 0 0 0 ...
 $ yearcount        : num  0 10 20 25 30 35 40 45 0 10 ...
 $ area_km          : num  180 180 180 180 180 ...
 $ irrperc          : num  0 0 0 0 0 ...
 $ irrfrac          : num  0 0 0 0 0 ...
 $ four_regions     : Factor w/ 4 levels "africa","americas",..: NA NA NA NA NA NA NA NA 3 3 ...
 $ eight_regions    : Factor w/ 8 levels "africa_north",..: NA NA NA NA NA NA NA NA 5 5 ...
 $ six_regions      : Factor w/ 6 levels "america","east_asia_pacific",..: NA NA NA NA NA NA NA NA 5 5 ...
 $ Latitude         : num  NA NA NA NA NA NA NA NA 33 33 ...
 $ Longitude        : num  NA NA NA NA NA NA NA NA 66 66 ...
 $ World.bank.region: Factor w/ 8 levels "","East Asia & Pacific",..: NA NA NA NA NA NA NA NA 7 7 ...
 $ population       : int  NA NA NA NA NA NA NA NA 9000000 11200000 ...
 $ log_pop          : num  NA NA NA NA NA ...
 $ log_pop_std      : num  NA NA NA NA NA ...
 $ income           : num  NA NA NA NA NA NA NA NA 2740 2570 ...
 $ log_income       : num  NA NA NA NA NA ...
 $ log_income_std   : num  NA NA NA NA NA ...
 $ GDPtot           : num  NA NA NA NA NA ...
 $ log_gdp_tot      : num  NA NA NA NA NA ...
 $ log_gdp_tot_std  : num  NA NA NA NA NA ...

Finally, lets check out a quick histogram of GDP and pop,

hist(aei$log_gdp_tot_std, breaks = 100)

hist(aei$log_pop_std, breaks = 100)

Dealing with Some Issues

There are a lot of countries that have no data for the regions, but have non zero irrperc/frac which I will use in further analysis, so we need to replace the regions.

#view which countries don't have regions but have non zero irrprec
na_regions <- aei[is.na(aei$four_regions),]

#Aruba
aei <- aei %>%
  mutate(four_regions = replace(four_regions, ISO == 'ABW', 'americas'), 
         six_regions = replace(six_regions, ISO == 'ABW', 'america'), 
         eight_regions = replace(eight_regions, ISO == 'ABW', 'america_north')) %>%
#american samoa
  mutate(four_regions = replace(four_regions,ISO == 'ASM', 'asia'), 
         six_regions = replace(six_regions,ISO == 'ASM', 'east_asia_pacific'), 
         eight_regions = replace(eight_regions,ISO == 'ASM', 'east_asia_pacific')) %>%
#bermuda
  mutate(four_regions = replace(four_regions,ISO == 'BMU', 'americas'), 
         six_regions = replace(six_regions,ISO == 'BMU', 'america'), 
         eight_regions = replace(eight_regions,ISO == 'BMU', 'america_north')) %>% 
#cote d'ivoire
  mutate(four_regions = replace(four_regions,ISO == 'CIV', 'africa'), 
         six_regions = replace(six_regions,ISO == 'CIV', 'sub_saharan_africa'), 
         eight_regions = replace(eight_regions,ISO == 'CIV', 'africa_sub_saharan')) %>% 
#democratic republic of congo
  mutate(four_regions = replace(four_regions,ISO == 'COD', 'africa'), 
         six_regions = replace(six_regions,ISO == 'COD', 'sub_saharan_africa'), 
         eight_regions = replace(eight_regions,ISO == 'COD', 'africa_sub_saharan')) %>% 
#republic of congo
  mutate(four_regions = replace(four_regions,ISO == 'COG', 'africa'), 
         six_regions = replace(six_regions,ISO == 'COG', 'sub_saharan_africa'), 
         eight_regions = replace(eight_regions,ISO == 'COG', 'africa_sub_saharan')) %>% 
#cayman islands
  mutate(four_regions = replace(four_regions,ISO == 'CYM', 'americas'), 
         six_regions = replace(six_regions,ISO == 'CYM', 'america'), 
         eight_regions = replace(eight_regions,ISO == 'CYM', 'america_north')) %>%
#Faroe islands
  mutate(four_regions = replace(four_regions,ISO == 'FRO', 'europe'), 
         six_regions = replace(six_regions,ISO == 'FRO', 'europe_central_asia'), 
         eight_regions = replace(eight_regions,ISO == 'FRO', 'europe_west')) %>%
#micronesia
  mutate(four_regions = replace(four_regions,ISO == 'FSM', 'asia'), 
         six_regions = replace(six_regions,ISO == 'FSM', 'east_asia_pacific'), 
         eight_regions = replace(eight_regions,ISO == 'FSM', 'east_asia_pacific')) %>%
#gibraltar
  mutate(four_regions = replace(four_regions,ISO == 'GIB', 'europe'), 
         six_regions = replace(six_regions,ISO == 'GIB', 'europe_central_asia'), 
         eight_regions = replace(eight_regions,ISO == 'GIB', 'europe_west')) %>%
#Guadeloupe
  mutate(four_regions = replace(four_regions,ISO == 'GLP', 'americas'), 
         six_regions = replace(six_regions,ISO == 'GLP', 'america'), 
         eight_regions = replace(eight_regions,ISO == 'GLP', 'america_north')) %>%
#greenland
  mutate(four_regions = replace(four_regions,ISO == 'GRL', 'europe'), 
         six_regions = replace(six_regions,ISO == 'GRL', 'europe_central_asia'), 
         eight_regions = replace(eight_regions,ISO == 'GRL', 'europe_west')) %>%
#french Guiana 
  mutate(four_regions = replace(four_regions,ISO == 'GUF', 'americas'), 
         six_regions = replace(six_regions,ISO == 'GUF', 'america'), 
         eight_regions = replace(eight_regions,ISO == 'GUF', 'america_south')) %>%
#guam
  mutate(four_regions = replace(four_regions,ISO == 'GUM', 'asia'), 
         six_regions = replace(six_regions,ISO == 'GUM', 'east_asia_pacific'), 
         eight_regions = replace(eight_regions,ISO == 'GUM', 'east_asia_pacific')) %>%
#Kyrgyzstan
  mutate(four_regions = replace(four_regions,ISO == 'KGZ', 'asia'), 
         six_regions = replace(six_regions,ISO == 'KGZ', 'europe_central_asia'), 
         eight_regions = replace(eight_regions,ISO == 'KGZ', 'asia_west')) %>%
#laos
  mutate(four_regions = replace(four_regions,ISO == 'LAO', 'asia'), 
         six_regions = replace(six_regions,ISO == 'LAO', 'east_asia_pacific'), 
         eight_regions = replace(eight_regions,ISO == 'LAO', 'east_asia_pacific')) %>%
#Macedonia
  mutate(four_regions = replace(four_regions,ISO == 'MKD', 'europe'), 
         six_regions = replace(six_regions,ISO == 'MKD', 'europe_central_asia'), 
         eight_regions = replace(eight_regions,ISO == 'MKD', 'europe_east')) %>%
#Martinique 
  mutate(four_regions = replace(four_regions,ISO == 'MTQ', 'americas'), 
         six_regions = replace(six_regions,ISO == 'MTQ', 'america'), 
         eight_regions = replace(eight_regions,ISO == 'MTQ', 'america_north')) %>%
#new caledonia
  mutate(four_regions = replace(four_regions,ISO == 'NCL', 'asia'), 
         six_regions = replace(six_regions,ISO == 'NCL', 'east_asia_pacific'), 
         eight_regions = replace(eight_regions,ISO == 'NCL', 'east_asia_pacific')) %>%
#puerto rico
 mutate(four_regions = replace(four_regions,ISO == 'PRI', 'americas'), 
         six_regions = replace(six_regions,ISO == 'PRI', 'america'), 
         eight_regions = replace(eight_regions,ISO == 'PRI', 'america_north')) %>%
#Palestine (West Bank + Gaza strip)
 mutate(four_regions = replace(four_regions,ISO == 'PSE', 'asia'), 
         six_regions = replace(six_regions,ISO == 'PSE', 'middle_east_north_africa'), 
         eight_regions = replace(eight_regions,ISO == 'PSE', 'asia_west')) %>%
#french Polynesia
  mutate(four_regions = replace(four_regions,ISO == 'PYF', 'asia'), 
         six_regions = replace(six_regions,ISO == 'PYF', 'east_asia_pacific'), 
         eight_regions = replace(eight_regions,ISO == 'PYF', 'east_asia_pacific')) %>%
#Reunion
  mutate(four_regions = replace(four_regions,ISO == 'REU', 'africa'), 
         six_regions = replace(six_regions,ISO == 'REU', 'sub_saharan_africa'), 
         eight_regions = replace(eight_regions,ISO == 'REU', 'africa_sub_saharan')) %>%
#Serbia, Montenegro, Kosovo
  mutate(four_regions = replace(four_regions,ISO == 'SMK', 'europe'), 
         six_regions = replace(six_regions,ISO == 'SMK', 'europe_central_asia'), 
         eight_regions = replace(eight_regions,ISO == 'SMK', 'europe_east')) %>%
#Slovakia
  mutate(four_regions = replace(four_regions,ISO == 'SVK', 'europe'), 
         six_regions = replace(six_regions,ISO == 'SVK', 'europe_central_asia'), 
         eight_regions = replace(eight_regions,ISO == 'SVK', 'europe_east')) %>%
#Turks and Caicos Islands
  mutate(four_regions = replace(four_regions,ISO == 'TCA', 'americas'), 
         six_regions = replace(six_regions,ISO == 'TCA', 'america'), 
         eight_regions = replace(eight_regions,ISO == 'TCA', 'america_north')) %>%
#East Timor
  mutate(four_regions = replace(four_regions,ISO == 'TLS', 'asia'), 
         six_regions = replace(six_regions,ISO == 'TLS', 'east_asia_pacific'), 
         eight_regions = replace(eight_regions,ISO == 'TLS', 'east_asia_pacific')) %>%
#taiwan
  mutate(four_regions = replace(four_regions,ISO == 'TWN', 'asia'), 
         six_regions = replace(six_regions,ISO == 'TWN', 'east_asia_pacific'), 
         eight_regions = replace(eight_regions,ISO == 'TWN', 'east_asia_pacific')) %>%
#British virgin Islands
  mutate(four_regions = replace(four_regions,ISO == 'VGB', 'americas'), 
         six_regions = replace(six_regions,ISO == 'VGB', 'america'), 
         eight_regions = replace(eight_regions,ISO == 'VGB', 'america_north')) %>%
#US Virgin Islands
  mutate(four_regions = replace(four_regions,ISO == 'VIR', 'americas'), 
         six_regions = replace(six_regions,ISO == 'VIR', 'america'), 
         eight_regions = replace(eight_regions, ISO == 'VIR', 'america_north')) 

Next time I’ll write a function.

There are also a lot of countries that have NA values for their income or population. Take a peek here.

lotanas <-  aei[rowSums(is.na(aei)) > 0,]
lotanas %>% 
  group_by(country) %>% 
  select(income, population) %>%  
  summarise_all(funs(sum(is.na(.))))
NA
NA

The countries that don’t have income also don’t have population, so as least I am consistent in my missing data. I have to move on so I will just leave this here for a minute. Perhaps later we should fill these variables.

Precipitation

Again, precipitation is translated output from LPJmL. Precipitation was chosen because it could be summed across countries, as other data could not (like discharge or ET). I have summed the precipitation by country and year. I am not sure whether I should scale or standardize precip, I will do all the possible combinations at the moment.

#precipitation
#cftandprecip is a script with all the grid cell values. 
cftandprecip <- read.csv('/Volumes/RachelExternal/Thesis/Thesis/Data/cft_and_precipdata.csv')
cftandprecip$ISO <- as.factor(cftandprecip$ISO)
cftandprecip <- cftandprecip[, -c(1)] #remove id col
cftandprecip <- subset(cftandprecip, year >= 1960)

#log and scale
precip <- 
  cftandprecip %>% 
  select(ISO, year, precipmm) %>% 
  group_by(ISO, year) %>% 
  summarise(preciptot = (sum(precipmm))) %>% #sum grid cells by ISO and year
  mutate(precip_sc = preciptot/max(preciptot)) %>% 
  mutate(precip_std = preciptot/mean(preciptot)) %>% 
  mutate(log_precip = log(preciptot+1)) %>% #1 is added here to prevent -Inf
  mutate(log_precip_sc = log_precip/max(log_precip)) %>% 
  mutate(log_precip_std = log_precip/mean(log_precip))

#merge
aei <- merge(aei, precip, by = c("ISO", "year"), all.x = TRUE)
rm(precip)

And some histograms to check out the scaled/standardized data.

hist(aei$preciptot, breaks = 100)

hist(aei$precip_sc, breaks = 100)

hist(aei$precip_std, breaks = 100)

hist(aei$log_precip, breaks = 100)

hist(aei$log_precip_sc, breaks = 100)

hist(aei$log_precip_std, breaks = 100)

Crop Fraction

Uff. Then comes crop fraction. As mentioned above individual crop fraction per grid cell is multiplied by respective grid cell area, summed on a country level giving ha of each crop grown per country. This was then divided by total area of the country to achieve the % area occupied by a certain crop per country.

#pull cft frac outta here
cft <- 
  cftandprecip %>% 
  select(-c(4)) %>% #removing precip
  mutate_each(funs(.*cellaream2), c(4:35)) %>% #multiply all fractions with the cell area
  group_by(ISO, year) %>% #group in to country and year
  summarise_each(funs(sum)) %>% #take col sums for each crop
  mutate(across(c(3:34), .fns = ~./cellaream2)) #divide col sums by total country area 

#removing categories with 0 (the biofuels and such)
cft <- cft[, -c(18, 19, 26, 34, 35)]

#and a merge
aei <- merge(aei, cft, by = c("ISO", "year"), all.x = TRUE)
rm(cft, cftandprecip)

Idk how to show the data here. Any ideas on representation would be helpful here.

Topographical

Topographical data is represented here by the data set from Riley, Degloria, and Elliot (1999) and is conviently available through the library(rethinking) from McElreath (2015). It provides a ruggedness factor for each country.

#rugged
data("rugged")
rug <- rugged %>% select(c("isocode", "rugged")) 
colnames(rug) <- c("ISO", "rugged")
#scaling
rug$rugged_sc <- rug$rugged / max(rug$rugged)
#merge
aei <- merge(aei, rug, by = "ISO", all.x = TRUE)
rm(rug, rugged)
hist(aei$rugged_sc, breaks = 100)


Time Series Evolution of Country Level Target Variable

Ok, so lets peek at how things change over time. Here is a graph of percentage of country area equipped for irrigation from 1960 - 2005.


pirrfrac <-
  ggplot(data = subset(aei, !is.na(irrperc)), 
         mapping = aes(x=year, y= irrperc, group = country, color = six_regions)) +
  geom_line() +
  scale_x_continuous() +
  theme(panel.grid = element_blank()) 

#run this separately, otherwise the plotly part doesn't work.
ggplotly(pirrfrac)
NA
NA

Although this graph has a lot of countries and can get quite messy, some general trends appear. South Asian countries seem to have high percentages of irrigated area per total land area (irrigation percentage). Then seemingly followed by East Asian and European countries. Africa and the Middle East do not seem to be irrigated as much. Be aware that you can these graphs are interactive, you may zoom, pan or click on the legend to isolate the regions. Although, a regional breakdown follows.

Sub-Saharan Africa

In general, Africa has low levels of irrigated area. Swaziland, Sao Tome and Principe, Reunion and Mauritius lead here with majority of others falling below the levels of these countries.

Europe and Centrtal Asia

Europe contains some countries that reach higher percentages of irrigated area. Countries such as the Netherlands, Romania, Albania, and Azerbaijan have reached peaks in the past (roughly 10-15% irrigated area) but seem to be in a decline towards the end our study period. Other countries such as Italy and Denmark have had more stable rises with less down turn toward. Unexpectedly, Russia has a very low percentage of irrigated area, however at this point, the assumption is that either Russia’s enormous size cancels out its irrigated area, or that Russia receives enough precipitation for the crops it grows that irrigation is not necessary. Further analysis should reveal this.

Americas

In the Americas, the % of area irrigated by countries is lower than Asia or Europe. Peaks here are Cuba and the Dominican Republic at around roughly 6-8% of their total countries being irrigated. There are some islands (Barbados and St. Lucia) that have sharp increases in irrigation fraction, but this could be because they are islands and any irrigation at all would induce the ration of irrigated land to total land spike. Counties that have experienced a steady increase, but are not the leaders in overall irrigation fraction are countries that are big and produce a lot of produce (USA, Mexico, Chile) The general trends of irrigation increase seem to be upward with perhaps a slight leveling off toward the end of the study period (for some countries) but lacking the distinct downturn that is seen in Europe.

East Asia and Oceania

The East Asian countries are quite high in % of irrigated area, when compared to the Americas or Africa. The four countries that reach upwards of (roughly) 10% or more of their total area irrigated toward the end of the study period are Vietnam, North Korea, South Korea, and Thailand. Other countries that have high irrfracs are China, Japan and the Philippines. It is expected that for this region the irrigation fraction would be high due to the amount of rice produced.

Oceania, due to its large amount of islands, does not have a lot of irrigation, majority of countries have 0% irrigation. New Zealand (around 2%) and Australia (less than 1%) have some irrigation. Although this could have a multitude of reasons why irrigation is so low here, regardless of the fact that Australia and New Zealand are very populous countries with mouths to feed. Australia is very large and perhaps its enormity cancels out the irrigated land it does have.

South Asia

Very few countries here, countries in this area are large. Very high levels of irrigation here coming from most countries. Bangladesh, Pakistan, and India are heavily irrigated compared to their land area.

Middle East and North Africa

Irrigation is also prevalent here (but not as much as in south Asia). These countries are dry and therefore would need irrigation to have domestic food supplies. Lebanon, Iraq and Israel lead here. Oil producing countries have little irrigation, they are dry and their GDP is high, perhaps importation is the easiest option for them?


Overall, this might be a good overview of what irrperc looks like for each region.


theme_set(theme_minimal())

ggplot(subset(aei, !is.na(irrperc)),
       aes(x=six_regions, y=irrperc, fill=six_regions)) + 
  geom_boxplot(show.legend = FALSE)  + 
  coord_flip() +
  theme(legend.title = element_blank())


References

McElreath, Richard. 2015. Statistical Rethinking: A Bayesian Course with Examples in R and Stan. CRC press. https://xcelab.net/rm/statistical-rethinking/.
Riley, Shawn, Stephen Degloria, and S. D. Elliot. 1999. “A Terrain Ruggedness Index That Quantifies Topographic Heterogeneity.” Internation Journal of Science 5 (January): 23–27.
Siebert, Stefan, Matti Kummu, Miina Porkka, Petra Doell, Navin Ramankutty, and Bridget Scanlon. 2015. “A Global Data Set of the Extent of Irrigated Land from 1900 to 2005.” Hydrology and Earth System Sciences 19 (March): 1521–45. https://doi.org/10.5194/hess-19-1521-2015.
Walker, W. R. 1989. FAO Irrigation and Drainage Paper 45.” 1. Vol. 45. Rome.
LS0tCnRpdGxlOiAiMiBDb3VudHJ5IExldmVsIERhdGEgQ2xlYW5pbmciCm91dHB1dDogCiAgaHRtbF9kb2N1bWVudDoKICB0b2M6IHllcwogIHRvY19mbG9hdDogeWVzCmJpYmxpb2dyYXBoeTogL1ZvbHVtZXMvUmFjaGVsRXh0ZXJuYWwvVGhlc2lzL1RoZXNpcy9iaWIuYmliCi0tLQoKYGBge3IgSG91c2VrZWVwaW5nLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KGJybXMpCmxpYnJhcnkocnN0YW4pCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkocGxvdGx5KQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkocmV0aGlua2luZykKbGlicmFyeShwdXJycikKbGlicmFyeShnZ2FuaW1hdGUpCmxpYnJhcnkod2JzdGF0cykKbGlicmFyeSh2aXJpZGlzKQpsaWJyYXJ5KHRtKQpsaWJyYXJ5KHdic3RhdHMpCmxpYnJhcnkodGliYmxlKQpsaWJyYXJ5KHN0cmluZ3IpCmxpYnJhcnkoZGlzdGlsbCkKYGBgCgoKCkxldHMgZG8gYSBzaG9ydCBpbnRyb2R1Y3Rpb24gdG8gd2hhdCB3ZSdyZSB3b3JraW5nIHdpdGggaGVyZS4gCgojIFRhcmdldCBWYXJpYWJsZSAgCiAgCiogJFkkIC0gSXJyaWdhdGlvbiBQZXJjZW50YWdlIC0gRG93bmxvYWRlZCB0aGUgZGF0YSBmcm9tIEBzaWViZXJ0R2xvYmFsRGF0YVNldDIwMTUgZGF0YSBzZXQgaW4gaGEvY291bnRyeS90aW1lc3RlcCwgdGhlbiBieSBkaXZpZGluZyBieSB0aGUgY291bnRyaWVzIHRvdGFsIGFyZWEsIHRoZSBmcmFjdGlvbiBvZiB0b3RhbCBsYW5kIGFyZWEgdGhhdCBpcyBpcnJpZ2F0ZWQgaW4gYSBnaXZlbiBjb3VudHJ5IGlzIGNyZWF0ZWQuIApgYGB7ciBTZXR0aW5nIHVwIENvdW50cnkgTGV2ZWwgZGYsIHdhcm5pbmc9RkFMU0V9CiNvcmlnaW5hbCBTaWViZXJ0IERhdGEKYWVpIDwtIHJlYWQuY3N2MigiL1ZvbHVtZXMvUmFjaGVsRXh0ZXJuYWwvVGhlc2lzL0RhdGEvU2llYmVydERhdGEvSElEX3YxMC9Db3VudHJ5X3RlbnllYXJfaGEuY3N2IikKYWVpIDwtIGFzLmRhdGEuZnJhbWUoYWVpKQoKI3JlbmFtZSB0aGUgY29scyBzbyB0aGF0IEkgY2FuIHVzZSB0aGVtIGFzIG51bWJlcgpjb2xuYW1lcyhhZWkpIDwtIGMoImNvdW50cnkiLCAiSVNPIiwgIklEIiwgIjE5MDAiLCAiMTkxMCIsIjE5MjAiLCIxOTMwIiwiMTk0MCIsIjE5NTAiLCIxOTYwIiwiMTk3MCIsIjE5ODAiLCIxOTg1IiwiMTk5MCIsIjE5OTUiLCIyMDAwIiwiMjAwNSIpCgojdGlkeWluZyBkYXRhIHRvIGxvbmcgZm9ybWF0CmFlaSA8LSBwaXZvdF9sb25nZXIoYWVpLGNvbHMgPSA0OjE3LCBuYW1lc190byA9ICJ5ZWFyIiwgdmFsdWVzX3RvID0gImFlaV9oYSIpCmFlaSRhZWlfaGEgPC0gcmVtb3ZlUHVuY3R1YXRpb24oYWVpJGFlaV9oYSkKYWVpJHllYXIgPC0gYXMubnVtZXJpYyhhZWkkeWVhcikKYWVpJGFlaV9oYSA8LSBhcy5udW1lcmljKGFlaSRhZWlfaGEpCmFlaSRJU08gPC0gYXMuZmFjdG9yKGFlaSRJU08pCmFlaSRjb3VudHJ5IDwtIGFzLmZhY3RvcihhZWkkY291bnRyeSkKI3N1YnNldCB0aGUgZGF0YSBzbyB0aGF0IGl0cyBmcm9tIHRoZSB5ZWFyIDE5NjAKYWVpIDwtIGFlaSAlPiUgc3Vic2V0KHllYXIgPj0gMTk2MCkKCiNtYWtlIGEgbmV3IGNvbCBmb3IgeWVhciBjb3VudAphZWkkeWVhcmNvdW50IDwtIChhZWkkeWVhciAtIDE5NjApCgojcmVtb3ZlIGRhdGEgZm9yIHRoZSB0b3RhbCBnbG9iYWwgaXJyaWdhdGVkIGFyZWEKZ2xvYmVhZWkgPC0gc3Vic2V0KGFlaSwgY291bnRyeSA9PSAiV09STEQiKQphZWk9IGFlaVshYWVpJGNvdW50cnkgPT0gIldPUkxEIixdCgpzdHIoYWVpKQpgYGAKCiAgICAgIApBZGRlZCB0byB0aGlzIHRvIGJlIGFibGUgdG8gY2FsY3VsYXRlIHRoZSAlIG9mIGxhbmQgaXJyaWdhdGVkIHBlciBjb3VudHJ5IHdlIG5lZWQgdGhlIGNvdW50cnkgYXJlYS4gVGhpcyBkYXRhIGlzIHRha2VuIGZyb20gV29ybGRiYW5rLiAgCgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojaW1wb3J0IHRoZSBkYXRhIHNldCB3aXRoIHRvdGFsIGNvdW50cnkgYXJlYSwgdGhpcyBjb21lcyBmcm9tIHRoZSBXb3JsZGJhbmsKY291bnRyeWFyZWEgPC0gcmVhZC5jc3YyKCIvVm9sdW1lcy9SYWNoZWxFeHRlcm5hbC9UaGVzaXMvRGF0YS9MYW5kQXJlYS9MYW5kQXJlYS5jc3YiKQoKI3JlbW92aW5nIGV4dHJhIGNvbHMKY291bnRyeWFyZWEgPC0gY291bnRyeWFyZWFbLWMoMjY1OjI3MCksIF0KY291bnRyeWFyZWEgPC0gY291bnRyeWFyZWFbLCAtYygxLCAzOjQpXQoKI2ZpeCB0aGUgY29sIG5hbWVzIChpbiB0aGUgdHdvIGRheXMgc2luY2UgaSBmb3VuZCB0aGlzIGxpdHRsZSBmb3IgbG9vcCBJIGxlYXJuZWQgaG93IHRvIGRvIHRoaXMgZmFzdGVyISkKZm9yICggY29sIGluIDI6bmNvbChjb3VudHJ5YXJlYSkpewogICAgY29sbmFtZXMoY291bnRyeWFyZWEpW2NvbF0gPC0gIHN1YigiWCIsICIiLCBjb2xuYW1lcyhjb3VudHJ5YXJlYSlbY29sXSkKfQpyZW1vdmUoY29sKQoKI21ha2luZyBsb25nIGRhdGEKY291bnRyeWFyZWEgPC0gCiAgY291bnRyeWFyZWEgJT4lICAKICBwaXZvdF9sb25nZXIoIUNvdW50cnkuQ29kZSwgbmFtZXNfdG8gPSAieWVhciIsIHZhbHVlc190byA9ICJhcmVhX2ttIikgJT4lIAogIHJlbmFtZShJU08gPSBDb3VudHJ5LkNvZGUpCgojZml4aW5nIHZhcmlhYmxlIHR5cGVzCmNvdW50cnlhcmVhJElTTyA8LSBhcy5mYWN0b3IoY291bnRyeWFyZWEkSVNPKQpjb3VudHJ5YXJlYSR5ZWFyIDwtIGFzLm51bWVyaWMoY291bnRyeWFyZWEkeWVhcikKc3RyKGNvdW50cnlhcmVhKQpgYGAKCgpGb3Igc29tZSByZWFzb24sIHRoZSBkYXRhIGZyb20gV29ybGRiYW5rIG9uIGVhY2ggY291bnRyaWVzIGFyZWEgb25seSBzdGFydHMgaW4gMTk2MS4gRm9yIHRoaXMgYW5hbHlzaXMsIDE5NjAgaXMgbmVlZGVkLiBDb3VudHJ5IGFyZWEgZnJvbSAxOTYxIHdpbGwgYmUgc3Vic3RpdHV0ZWQgZm9yIDE5NjAsIHdpdGggdGhlIGFzc3VtcHRpb24gdGhhdCBjb3VudHJ5IGFyZWEgZG9lc24ndCBjaGFuZ2UgZHJhc3RpY2FsbHkgaW4gb25lIHllYXIgKGl0IGRvZXNuJ3QpLiAgCgpgYGB7ciB3YXJuaW5nID0gRkFMU0V9CmhlYWQoc3Vic2V0KGNvdW50cnlhcmVhLCBjKHllYXIgPT0gMTk2MCB8IHllYXIgPT0gMTk2MSkpKSAKCiNmaXhpbmcgMTk2MApjb3VudHJ5YXJlYSA8LQogIGNvdW50cnlhcmVhICU+JSAKICBncm91cF9ieShJU08pICU+JSAKICBmaWxsKGFyZWFfa20sIC5kaXJlY3Rpb24gPSAidXAiKSAlPiUgCiAgdW5ncm91cCgpCgpgYGAKCk1lcmdlIHRoZSBjb3VudHJ5IGFyZWEgd2l0aCB0aGUgQUVJIGRmIGhlcmUuICAgCgpgYGB7ciBKb2luIENBciB9CiNjb21iaW5lIHRoZXNlIGRhdGEgc2V0cwphZWkgPC0gYWVpICU+JSBtZXJnZSh5ID0gY291bnRyeWFyZWEsIGJ5LnggPSBjKCJJU08iLCAieWVhciIpLCBhbGwueCA9IFRSVUUpCgpybShjb3VudHJ5YXJlYSkKaGVhZChhZWkpCmBgYAoKU29tZSBjb3VudHJpZXMgYWxzbyBoYXZlIG5vIGFyZWEgdmFsdWUuIEknbGwgZ28gdGhyb3VnaCBhbmQgc2VlIGlmIGFueSBvZiB0aGUgY291bnRyaWVzIHdpdGggbWlzc2luZyBhcmVhIHZhbHVlcyBoYXZlIG5vbiB6ZXJvIEFFSV9oYS4gSWYgc28sIEknbGwgcmVwbGFjZSB0aGVtLCBhcyB0aGV5IGRpZG4ndCBjb21lIHRocm91Z2ggd2l0aCB0aGUgV29ybGRCYW5rIGRhdGEgc2V0IGJ1dCBhcmUgb25saW5lLiBDb3B5aW5nIGFuZCBwYXN0aW5nIGZyb20gdmFyaW91cyBzb3VyY2VzIHNob3VsZCBiZSBmaW5lLgoKCmBgYHtyIEZpeGVzIGZvciBDQXJ9CiNjaGVja2luZyBmb3IgY291bnRyaWVzIHdpdGggTkEgdmFsdWVzIGluIHRoZWlyIGFyZWFfa20gY29sCiNsb29raW5nIHByaW1hcmlseSBmb3IgY291bnRyaWVzIHRoYXQgaGF2ZSBub24gMCBBRUlfaGEKYWVpW2lzLm5hKGFlaSRhcmVhX2ttKSxdCiAgICAgICAgICAgICAgICAKI2ZpeGluZyBjb3VudGllcyB3aXRoIG5vIGFyZWEKYWVpJGFyZWFfa21bd2hpY2goYWVpJElTTyA9PSAiR1VGIildIDwtIDgzNTM0ICNGcmVuY2ggR3VpYW5hIGZyb20gQnJpdGFubmljYQphZWkkYXJlYV9rbVt3aGljaChhZWkkSVNPID09ICJHTFAiKV0gPC0gMTYzMCAjR3VhZGVsb3VwZSBmcm9tIEJyaXRhbm5pY2EgCmFlaSRhcmVhX2ttW3doaWNoKGFlaSRJU08gPT0gIk1UUSIpXSA8LSAxMTI4ICMgTWFydGluaXF1ZSBmcm9tIEJyaXRhbm5pY2EKYWVpJGFyZWFfa21bd2hpY2goYWVpJElTTyA9PSAiUkVVIildIDwtIDI1MTIgI1JldW5pb24gZnJvbSBCcml0YW5uaWNhCmFlaSRhcmVhX2ttW3doaWNoKGFlaSRJU08gPT0gIlNNSyIpXSA8LSAxMzgxMiArIDEwOTA1ICsgNzc1ODkgI01vbnRlbmVncm8gKyBLb3Nvdm8gKyBTZXJiaWEgZnJvbSBCcml0YW5uaWNhCmFlaSRhcmVhX2ttW3doaWNoKGFlaSRJU08gPT0gIlRXTiIpXSA8LSAzNTk4MCAjVGFpd2FuIGZyb20gQ0lBLmdvdgphZWkkYXJlYV9rbVt3aGljaChhZWkkSVNPID09ICJTRE4iKV0gPC0gMTg4MjAwMCAjU3VkYW4gZnJvbSBVTkRQCmBgYAoKCk5vdywgdHJhbnNmb3JtIHRoZSBBRUlfaGEgdG8gJGttXjIkIGFuZCBkaXZpZGUgdG8gZ2V0IHRoZSAlIG9mIHRvdGFsIGNvdW50cnkgYXJlYSB0aGF0IGlzIGVxdWlwcGVkIGZvciBpcnJpZ2F0aW9uLiBUaGVyZSBhcmUgc3RpbGwgc29tZSBjb3VudHJpZXMgdGhhdCBoYXZlIDAgQUVJX2hhIGFuZCBubyBhcmVhX2ttIHZhbHVlLiBJIHRoaW5rIEkgd2lsbCBhc3NpZ24gdGhlIGlycmZyYWMvcGVyYyAwIHRvIHRob3NlIGNvdW50cmllcywgYnV0IGxldHMgd2FpdCBhIGxpdHRsZSB3aGlsZSB0byBkbyB0aGF0LCBtb3N0IGFyZSBpc2xhbmRzLiAgCgpgYGB7ciBDcmVhdGluZyBUYXJnZXQgVmFyaWFibGV9CmFlaSA8LSBhZWkgJT4lIG11dGF0ZShpcnJwZXJjID0gKChhZWlfaGEvMTAwKS9hcmVhX2ttKSoxMDAsIGlycmZyYWMgPSAoKGFlaV9oYS8xMDApL2FyZWFfa20pKQpgYGAKCkhlcmUgaXMgYSBxdWljayBoaXN0b2dyYW0gb2YgdGhlIHRhcmdldCB2YXJpYWJsZS4gQSBsb3Qgb2YgMHMuIAoKYGBge3IgSGlzdCBvZiBUVmFyfQpoaXN0KGFlaSRpcnJwZXJjLCBicmVha3MgPSAyMDApCmBgYAoKKioqCgojIENob3NlbiBQcmVkaWN0b3IgVmFyaWFibGVzICAKCkFjY29yZGluZyB0byB0aGUgRkFPIFtAd2Fsa2VyRkFPSXJyaWdhdGlvbkRyYWluYWdlMTk4OV0sIHRoZSBjaG9pY2Ugb2Ygd2hpY2ggaXJyaWdhdGlvbiwgYW5kIGJ5IHByb3h5IHdoZXRoZXIgdG8gaXJyaWdhdGUgb3Igbm90LCBjb21lcyBmcm9tIHNpeCBmYWN0b3JzLiBUaGUgcHJlZGljdG9yIHRoYXQgd2lsbCBiZSB1c2VkIGZvciB0aGlzIGFuYWx5c2lzIGFyZSBsaXN0ZWQgYmVsb3c6ICAKCi0gRWNvbm9taWMgCgogIC0gJE1fYyQgLSBHRFAgcGVyIENhcGl0YSAtIEVhY2ggY291bnRyeSdzIEdEUCBwZXIgQ2FwaXRhIGZyb20gR2FwbWluZGVyLCB3aGljaCBjb2xsZWN0cyBkYXRhIGZyb20gdGhlIFVOIGFuZCB0aGUgTWFkZGlzb24gcHJvamVjdC4gVGhpcyB2YXJpYWJsZSB3aWxsIGJlIGxvZ2dlZCBiZWNhdXNlIGFzIHN0YXRlZCBpbiAqU3RhdGlzdGljYWwgUmV0aGlua2luZyogW0BtY2VscmVhdGhTdGF0aXN0aWNhbFJldGhpbmtpbmdCYXllc2lhbjIwMTVdIE1jRWxyZWF0aCBzdGF0ZXMgKHBnLiAyMzkpLCAiV2UgdXNlIHRoZSBsb2dhcml0aG0gb2YgaXQsIGJlY2F1c2UgdGhlIGxvZ2FyaXRobSBvZiBHRFAgaXMgdGhlICptYWduaXR1ZGUqIG9mIEdEUC4gU2luY2Ugd2VhbHRoIGdlbmVyYXRlcyB3ZWFsdGgsIGl0IHRlbmRzIHRvIGJlIGV4cG9uZW50aWFsbHkgcmVsYXRlZCB0byBhbnl0aGluZyB0aGF0IGluY3JlYXNlcyBpdCIKICAKLSBUb3BvZ3JhcGhpY2FsICAgCgogIC0gJFJ1X2MkIC0gUmVwcmVzZW50ZWQgaGVyZSB1c2luZyB0aGUgInJ1Z2dlZCIgZGF0YSBzZXQgZnJvbSByZXRoaW5raW5nLCBpbiB3aGljaCBhIGNvZWZmIG9mIHJ1Z2dlZG5lc3MgZm9yIGVhY2ggY291bnRyeSB3YXMgYXNzaWduZWQuIFRoaXMgZGF0YSB3YXMgdGFrZW4gZnJvbSBAcmlsZXlUZXJyYWluUnVnZ2VkbmVzc0luZGV4MTk5OQogIAotIFNvaWwgVHlwZSAgCgogIC0gVGhpcyB3aWxsIG5vdCBiZSBpbmNsdWRlZCBpbiB0aGlzIGFuYWx5c2lzLiBBbHRob3VnaCwgaXQgY291bGQgYmUgdXNlZnVsIHRoZXJlIGlzIG5vIGdvb2Qgd2F5IHRvIHF1YW50aWZ5IHNvaWwgdHlwZSBvbiBhIGNvdW50cnkgbGV2ZWwgYmFzaXMuIFRoaXMgd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgZ3JpZCBjZWxsIG1vZGVsLCBhcyByZWdpb25zIGNhbiBiZSBlYXNpbHkgaW50ZWdyYXRlZCB3aXRoIHRoZSBncmlkIGNlbGwgc3RydWN0dXJlLiAKCi0gV2F0ZXIgU3VwcGx5ICAgIAoKICAtICRSX2MkIC0gVG90YWwgUHJlY2lwaXRhdGlvbiAtICBUcmFuc2xhdGVkIG91dHB1dCBmcm9tIExQSm1MLiBTdW1tZWQgYWNyb3NzIHR3byBkaW1lbnNpb25zOiBtb250aCBhbmQgY291bnRyeS4gSW4gbW0vY291bnRyeS95ZWFyICAKLSBDcm9wIFR5cGUgIAoKICAtIEZyYWN0aW9uIG9mIGVhY2ggY3JvcCBncm93biBwZXIgY291bnRyeSAtICBUcmFuc2xhdGVkIG91dHB1dCBmcm9tIExQSm1MLiBJbmRpdmlkdWFsIGNyb3AgZnJhY3Rpb24gcGVyIGdyaWQgY2VsbCBtdWx0aXBsaWVkIGJ5IHJlc3BlY3RpdmUgZ3JpZCBjZWxsIGFyZWEsIHN1bW1lZCBvbiBhIGNvdW50cnkgbGV2ZWwgZ2l2aW5nIGhhIG9mIGVhY2ggY3JvcCBncm93biBwZXIgY291bnRyeS4gVGhpcyB3YXMgdGhlbiBkaXZpZGVkIGJ5IHRvdGFsIGFyZWEgb2YgdGhlIGNvdW50cnkgdG8gYWNoaWV2ZSB0aGUgJSBhcmVhIG9jY3VwaWVkIGJ5IGEgY2VydGFpbiBjcm9wIHBlciBjb3VudHJ5LiBTdGlsbCB3b3JraW5nIG91dCBob3cgdG8gd29yayB3aXRoIHRoaXMgcHJlZGljdG9yLiAKCi0gU29jaWFsIEluZmx1ZW5jZXMgIAoKICAtICRQX2MkIC0gVG90YWwgUG9wdWxhdGlvbiAtIEVhY2ggY291bnRyeSdzIHRvdGFsIHBvcHVsYXRpb24gb24gYSB5ZWFybHkgYmFzaXMuIFRha2VuIGZyb20gR2FwbWluZGVyLiBBZ2FpbiwgdGhpcyB3aWxsIGJlIGxvZ2dlZCwgZHVlIHRvIHRoZSBzYW1lIGFyZ3VtZW50IGZvciBHRFAsIGFuZCBjZW50ZXJlZC4KICAKQWxsIHZhcmlhYmxlcyB3aWxsIGJlIHNjYWxlZCBvciBjZW50ZXJlZC4gCgoKRmlyc3QsIHRoZSBJU08gY29kZXMgYW5kIFJlZ2lvbnMgdG8gYmUgYWJsZSB0byBob2xkIHNvbWUgc3RydWN0dXJlLiAgCgpgYGB7cn0KI3RoZSBJU08gY29kZXMgYW5kIHJlZ2lvbmFsIGRhdGEgZnJvbSBHYXBtaW5kZXIKaXNvIDwtIHJlYWQuY3N2MigiL1ZvbHVtZXMvUmFjaGVsRXh0ZXJuYWwvVGhlc2lzL1RoZXNpcy9EYXRhL0dBUG1pbmRlcl9JU09jb2Rlcy5jc3YiKQppc28gPC0gaXNvWywgLWMoMiw3LDEwLDEyLDEzKV0gI3JlbW92aW5nIGV4dHJhIGluZm8KCiNyZW5hbWluZyBzb21lIGNvbHMKaXNvIDwtIAogIGlzbyAlPiUgCiAgcmVuYW1lKElTTyA9IEdFTywgY291bnRyeSA9IG5hbWUpCgojZml4aW5nIHRoZSB2YXJpYWJsZSB0eXBlcwppc28kSVNPIDwtIGFzLmZhY3Rvcihpc28kSVNPKQppc28kY291bnRyeSA8LSBhcy5mYWN0b3IoaXNvJGNvdW50cnkpCmlzbyRmb3VyX3JlZ2lvbnMgPC0gYXMuZmFjdG9yKGlzbyRmb3VyX3JlZ2lvbnMpCmlzbyRlaWdodF9yZWdpb25zIDwtIGFzLmZhY3Rvcihpc28kZWlnaHRfcmVnaW9ucykKaXNvJHNpeF9yZWdpb25zIDwtIGFzLmZhY3Rvcihpc28kc2l4X3JlZ2lvbnMpCmlzbyRzaXhfcmVnaW9ucyA8LSBhcy5mYWN0b3IoaXNvJHNpeF9yZWdpb25zKQppc28kV29ybGQuYmFuay5yZWdpb24gPC0gYXMuZmFjdG9yKGlzbyRXb3JsZC5iYW5rLnJlZ2lvbikKc3RyKGlzbykKCiNwYXN0IG1lIGhlbHBpbmcgZnV0dXJlIG1lCiNmaXhpbmcgTWFjZWRvbmlhLCBGWVIgdG8gTm9ydGggTWFjZWRvbmlhCmlzbyRjb3VudHJ5IDwtIGFzLmNoYXJhY3Rlcihpc28kY291bnRyeSkKaXNvW2lzbyA9PSAiTWFjZWRvbmlhLCBGWVIiXSA8LSAiTm9ydGggTWFjZWRvbmlhIgppc28kY291bnRyeSA8LSBhcy5mYWN0b3IoaXNvJGNvdW50cnkpCmBgYApDb29sLCB3ZSBoYXZlIG11bHRpcGxlIHJlZ2lvbnMgaGVyZSB0aGF0IHdlIGNvdWxkIHVzZSBpbiB0aGUgZnV0dXJlIGZvciBzb21lIG11bHRpbGV2ZWwgYnVzaW5lc3MuIEFsc28sIGxhdGl0dWRlIGFuZCBsb25naXR1ZGUgaXMgaGVyZSwgd2hpY2ggd2UgY2FuIGFsc28gdHJ5IGxhdGVyLiBPYnZpb3VzbHkgdGhlc2UgbGF0IGFuZCBsb24gbWVhc3VyZW1lbnRzIHdpbGwgbWVhbiBub3RoaW5nIGZvciBhIGNvdW50cnkgbGlrZSBDaGluYSBvciB0aGUgVVNBLCBidXQgdGhleSBhcmUgbmljZSB0byBoYXZlLiAgICAKCgojIyBJbmNvbWUKCkluY29tZSBkYXRhIGlzIGNvbWluZyBmcm9tIEdhcG1pbmRlciwgYXMgdGhleSBoYXZlIHB1dCByZWFsIGVmZm9ydCBpbiB0byBmaWxsaW5nIGFsbCB0aGUgZ2FwcyBpbiBpbmNvbWUgYW5kIHBvcHVsYXRpb24gZm9yIHRoZSBsYXN0IDE1MCB5ZWFycy4gSW5jb21lIGlzIGluIHRlcm1zIG9mIHRoZSAyMDExIFVTRCBhbmQgaXMgaW5mbGF0aW9uIGFkanVzdGVkLiAgCgpgYGB7cn0KI2luY29tZSBoZXJlIGlzIDIwMTEgdXNkIAppbmNvbWUgPC0gcmVhZC5jc3YoIi9Wb2x1bWVzL1JhY2hlbEV4dGVybmFsL1RoZXNpcy9UaGVzaXMvRGF0YS9HYXBtaW5kZXJfaW5jb21lX3Blcl9wZXJzb25fZ2RwcGVyY2FwaXRhX3BwcF9pbmZsYXRpb25fYWRqdXN0ZWQuY3N2IikKaW5jb21lIDwtIGluY29tZVssIGMoMSwgMTYyOjIwNyldICNyZW1vdmluZyBleHRyYSB5ZWFycwoKI21ha2luZyBsb25nIGRhdGEKaW5jb21lIDwtIAogIGluY29tZSAlPiUgIAogIHBpdm90X2xvbmdlcighY291bnRyeSwgbmFtZXNfdG8gPSAieWVhciIsIHZhbHVlc190byA9ICJpbmNvbWUiKSAKCiNzdGlsbCBoYXZlIHRoZSB4cyB0aGVyZQppbmNvbWUkeWVhciA8LSBzdHJfcmVtb3ZlX2FsbChpbmNvbWUkeWVhciwgIltYXSIpCiN0cmFuc2Zvcm1hdGlvbiBvZiB0aGUgdmFyaWFibGUgdHlwZXMKaW5jb21lJHllYXIgPC0gYXMubnVtZXJpYyhpbmNvbWUkeWVhcikKaW5jb21lJGNvdW50cnkgPC0gYXMuZmFjdG9yKGluY29tZSRjb3VudHJ5KQoKI2xvZyBhbmQgc3RhbmRhcmRpemUKaW5jb21lJGxvZ19pbmNvbWUgPC0gbG9nKGluY29tZSRpbmNvbWUpCmluY29tZSA8LSBpbmNvbWUgJT4lIAogIG11dGF0ZShsb2dfaW5jb21lX3N0ZCA9IGxvZ19pbmNvbWUgLyBtZWFuKGxvZ19pbmNvbWUpKQoKI2Egc3VtbWFyeQpzdW1tYXJ5KGluY29tZSkKCiNwYXN0IG1lIGhlbHBpbmcgZnV0dXJlIG1lIGFnYWluCiNmaXhpbmcgRXN3YXRpbmkgdG8gU3dhemlsYW5kIChldmVuIHRob3VnaCBFc3dhdGluaSBpcyB0aGUgY29ycmVjdCBuYW1lKQppbmNvbWUkY291bnRyeSA8LSBhcy5jaGFyYWN0ZXIoaW5jb21lJGNvdW50cnkpCmluY29tZVtpbmNvbWUgPT0gIkVzd2F0aW5pIl0gPC0gIlN3YXppbGFuZCIKaW5jb21lJGNvdW50cnkgPC0gYXMuZmFjdG9yKGluY29tZSRjb3VudHJ5KQoKYGBgCgpMb2dnaW5nIGFuZCBzdGFuZGFyZGl6aW5nIGlzIG5lY2Vzc2FyeSBoZXJlLiBBZ2FpbiwgdGhlIGFyZ3VtZW50IGlzIHRoYXQgd2VhbHRoIGJlZ2V0cyB3ZWFsdGgsIHNvIGluY29tZSBpcyBsb2dhcml0aG1pYy4gRnJvbSB0aGVyZSBqdXN0IGNlbnRlciB0aGUgbWVhbiBhdCAwIHdpdGggYSBzdGRldiBvZiAxIGZvciBzdGFuZGFyZGl6YXRpb24uICAKCgoKIyMgUG9wdWxhdGlvbgoKUG9wdWxhdGlvbiBkYXRhIGlzIGFsc28gdGFrZW4gZnJvbSBHYXBtaW5kZXIuIFRoZSBzYW1lIHByb2Nlc3Mgb2YgbG9nZ2luZyBhbmQgc3RhbmRhcmRpemluZyB3aWxsIGJlIGNhcnJpZWQgb3V0IGhlcmUuIAoKYGBge3J9CiNwb3B1bGF0aW9uIGRhdGEgYWxzbyB0YWtlbiBmcm9tIEdhcG1pbmRlcgpwb3B1bGF0aW9uIDwtIHJlYWQuY3N2KCIvVm9sdW1lcy9SYWNoZWxFeHRlcm5hbC9UaGVzaXMvVGhlc2lzL0RhdGEvR2FwbWluZGVyX3BvcHVsYXRpb25fdG90YWwuY3N2IikKCiNyZW1vdmluZyBleHRyYSB5ZWFycwpwb3B1bGF0aW9uIDwtIHBvcHVsYXRpb25bLCBjKDEsIDE2MjoyMDcpXSAKI21ha2luZyBsb25nZXIgZGF0YQpwb3B1bGF0aW9uIDwtIAogIHBvcHVsYXRpb24gJT4lICAKICBwaXZvdF9sb25nZXIoIWNvdW50cnksIG5hbWVzX3RvID0gInllYXIiLCB2YWx1ZXNfdG8gPSAicG9wdWxhdGlvbiIpIAoKI3JlbW92aW5nIHRoZSBYcyBmcm9tIHRoZSB5ZWFyIHN0cmluZ3MKcG9wdWxhdGlvbiR5ZWFyIDwtIHN0cl9yZW1vdmVfYWxsKHBvcHVsYXRpb24keWVhciwgIltYXSIpCgojZml4aW5nIHZhcmlhYmxlIHR5cGVzCnBvcHVsYXRpb24kY291bnRyeSA8LSBhcy5mYWN0b3IocG9wdWxhdGlvbiRjb3VudHJ5KQpwb3B1bGF0aW9uJHllYXIgPC0gYXMubnVtZXJpYyhwb3B1bGF0aW9uJHllYXIpCgojbG9nIGFuZCBzdGFuZGFyZGl6ZSwgc2FtZSBhcmd1bWVudCBhcyBpbmNvbWU6IHBvcHVsYXRpb24gYmVnZXRzIHBvcHVsYXRpb24KcG9wdWxhdGlvbiRsb2dfcG9wIDwtIGxvZyhwb3B1bGF0aW9uJHBvcHVsYXRpb24pCnBvcHVsYXRpb24gPC0gcG9wdWxhdGlvbiAlPiUgCiAgbXV0YXRlKGxvZ19wb3Bfc3RkID0gbG9nX3BvcCAvIG1lYW4obG9nX3BvcCkpCgpzdW1tYXJ5KHBvcHVsYXRpb24pCgojYW5ubmQgYWdhaW4uLi4KI2ZpeGluZyBFc3dhdGluaSB0byBTd2F6aWxhbmQgKGV2ZW4gdGhvdWdoIEVzd2F0aW5pIGlzIHRoZSBjb3JyZWN0IG5hbWUpCnBvcHVsYXRpb24kY291bnRyeSA8LSBhcy5jaGFyYWN0ZXIocG9wdWxhdGlvbiRjb3VudHJ5KQpwb3B1bGF0aW9uW3BvcHVsYXRpb24gPT0gIkVzd2F0aW5pIl0gPC0gIlN3YXppbGFuZCIKcG9wdWxhdGlvbiRjb3VudHJ5IDwtIGFzLmZhY3Rvcihwb3B1bGF0aW9uJGNvdW50cnkpCmBgYAoKU28gc29tZSBpc3N1ZXMgYXJpc2UgaGVyZSB3aXRoIHRoZSBmYWN0IHRoYXQgd2UgaGF2ZSBkaWZmZXJlbnQgY291bnRyeSBkYXRhIGZvciBlYWNoIGRhdGFmcmFtZS4gU29tZXRpbWVzIHRoZSBuYW1lcyBhcmUgY2FwaXRhbGl6ZWQsIG90aGVyIHRpbWVzIHRoZXJlIGFyZSBzcGFjZXMgaW5zdGVhZCBvZiB1bmRlcnNjb3Jlcy4gQnkgdXNpbmcgYGFudGlfam9pbigpYCBJIGNhbiBzZWUgd2hhdCB3b24ndCBiZSBqb2luZWQuIEFsc28gdGhpcyBnb2VzIGJvdGggd2F5cywgYGFudGlfam9pbigpYCByZXR1cm5zIHJvd3Mgb2YgeCB0aGF0IGRvIG5vdCBoYXZlIGEgbWF0Y2ggaW4geS4gIAoKYGBge3J9Cmlzb3BvcCA8LSBhbnRpX2pvaW4oaXNvLCBwb3B1bGF0aW9uLCBieSA9ICJjb3VudHJ5IikKc3VtbWFyeShpc29wb3ApCgpwb3Bpc28gPC0gYW50aV9qb2luKHBvcHVsYXRpb24sIGlzbywgYnkgPSAiY291bnRyeSIpCnN1bW1hcnkocG9waXNvKQpgYGAKCldlbnQgYmFjayB1cCBhbmQgc29sdmVkIHRoZSBpc3N1ZSBvZiBOb3J0aCBNYWNlZG9uaWEgYW5kIFN3YXppbGFuZC4gVGhlcmUgYXJlIHN0aWxsIGlzc3VlcyB3aXRoIEhvbmcgS29uZyBhbmQgVGFpd2FuIGFzIHRoZXkgYXJlIHBhcnQgb2YgQ2hpbmEuIElTTyBoYXMgZGF0YSBmb3IgSG9uZyBLb25nIGFuZCBUYWl3YW4gdGhhdCBwb3B1bGF0aW9uIGRvZXMgbm90IGhhdmUuICBJIHdvbnQgaW5jbHVkZSB0aGVtIGluIHRoZSBIVE1MIGJ1dCB0aGV5IGFyZSBpbiB0aGUgY29kZS4gIAoKYGBge3IgaW5jbHVkZT1GQUxTRX0KaXNvaW5jIDwtIGFudGlfam9pbihpc28sIGluY29tZSwgYnkgPSAiY291bnRyeSIpCnN1bW1hcnkoaXNvaW5jKQoKaW5jaXNvIDwtIGFudGlfam9pbihpbmNvbWUsIGlzbywgYnkgPSAiY291bnRyeSIpCnN1bW1hcnkoaW5jaXNvKQpgYGAKCgpgYGB7ciBpbmNsdWRlPUZBTFNFfQpwb3BpbmMgPC0gYW50aV9qb2luKHBvcHVsYXRpb24sIGluY29tZSwgYnkgPSAiY291bnRyeSIpCnN1bW1hcnkocG9waW5jKQoKaW5jcG9wIDwtIGFudGlfam9pbihpbmNvbWUsIHBvcHVsYXRpb24sIGJ5ID0gImNvdW50cnkiKQpzdW1tYXJ5KGluY3BvcCkKYGBgCgoKQWxyaWdodCwgc28gSSB3aWxsIGxlZnQgam9pbiBJU08gYW5kIHBvcHVsYXRpb24gdGhlbiBhZ2FpbiB3aXRoIGluY29tZT8gTm90IHN1cmUgdGhhdCB0aGlzIHdpbGwgc29sdmUgbXkgcHJvYmxlbSwgYnV0IGxldHMgdHJ5IGl0LgpgYGB7cn0KI3JlbW92ZSBhbGwgdGhlc2UgcmFuZG8gdGFibGVzCnJtKHBvcGluYywgaW5jaXNvLCBpbmNwb3AsIHBvcGlzbywgaXNvaW5jLCBpc29wb3ApCgojCmlzbyA8LSBsZWZ0X2pvaW4oaXNvLCBwb3B1bGF0aW9uLCBieSA9ICJjb3VudHJ5IikKaXNvIDwtIGxlZnRfam9pbihpc28sIGluY29tZSwgYnkgPSBjKCJjb3VudHJ5IiwgInllYXIiKSkKCiMgYWxyaWdodCAxOTcgY291bnRyaWVzISB3aG9vcCEKc3RyKGlzbykKCnJtKGluY29tZSwgcG9wdWxhdGlvbikKYGBgCgpOb3csIGpvaW4gSVNPIHRvIEFFSSB3aXRoIGEgbWVyZ2UgKGNhdXNlIGluIHRoaXMgY2FzZSB0aGUgZHluYW1pY3Mgb2YgbWVyZ2UgYXJlIGNsZWFyZXIgZm9yIG1lKS4gSG9waW5nIHRvIHByZXNlcnZlIGFsbCBkYXRhISAKCmBgYHtyfQphZWkgPC0gbWVyZ2UoYWVpLCBpc28sIGJ5ID0gYygiSVNPIiwiY291bnRyeSIsICJ5ZWFyIiksIGFsbC54ID0gVFJVRSkKcm0oaXNvKQpzdHIoYWVpKSAKYGBgCgpTb2x2ZWQgdGhlIGlzc3VlLCAyMzIgZmFjdG9ycyBmb3IgYm90aCBjb3VudHJpZXMgYW5kIElTTywgbWVhbmluZyB0aGF0IHdlIGhhdmUgYmVlbiB1c2luZyB0aGUgb3JpZ2luYWwgQUVJIGZpbGUgZnJvbSBTaWViZXJ0IGFzIHRoZSBtYWluIGRhdGEgZnJhbWUgdG8gam9pbiB0by4gR29vZC4gVGhpcyBpcyB0aGUgZGF0YSB0aGF0IG5lZWRzIHRvIGJlIG1haW50YWluZWQsIE5BcyBjYW4gcG9wIHVwIGluIG90aGVyIGNvbHMgYnV0IG5vdCBpcnJpZ2F0ZWQgYXJlYS4gICAKCkJ1dCBJIHN0aWxsIHdvdWxkIGxpa2UgdG90YWwgR0RQIGZvciBsYXRlciBzbyBsZXRzIHRyYW5zZm9ybSB1c2luZyBwb3B1bGF0aW9uLiAKYGBge3J9CmFlaSRpbmNvbWUgPC0gYXMubnVtZXJpYyhhZWkkaW5jb21lKSAKCiNtdXRhdGluZyBmb3IgdG90YWwgR0RQIGFuZCBsb2cgR0RQCmFlaSA8LQogIGFlaSAlPiUKICBtdXRhdGUoR0RQdG90ID0gaW5jb21lKnBvcHVsYXRpb24pICU+JQogIG11dGF0ZShsb2dfZ2RwX3RvdCA9IGxvZyhHRFB0b3QpKSAKCiNjcmVhdGluZyB0aGUgZGYgdG8gc3RhbmRhcmRpemUgd2l0aG91dCB0aGUgTkFzCmFlaTIgPC0KICBhZWkgJT4lIAogIHNlbGVjdChJU08sIHllYXIsIGxvZ19nZHBfdG90KSAlPiUKICBuYS5vbWl0KCkgJT4lIAogIG11dGF0ZShsb2dfZ2RwX3RvdF9zdGQgPSBsb2dfZ2RwX3RvdC9tZWFuKGxvZ19nZHBfdG90KSkgJT4lIAogIHNlbGVjdChJU08sIHllYXIsIGxvZ19nZHBfdG90X3N0ZCkKCiNub3cgcmVqb2luIQphZWkgPC0gCiAgbGVmdF9qb2luKGFlaSwgYWVpMiwgYnkgPSBjKCJJU08iLCAieWVhciIpKQoKc3RyKGFlaSkKYGBgCgoKRmluYWxseSwgbGV0cyBjaGVjayBvdXQgYSBxdWljayBoaXN0b2dyYW0gb2YgR0RQIGFuZCBwb3AsCmBgYHtyfQpoaXN0KGFlaSRsb2dfZ2RwX3RvdF9zdGQsIGJyZWFrcyA9IDEwMCkKYGBgCgpgYGB7cn0KaGlzdChhZWkkbG9nX3BvcF9zdGQsIGJyZWFrcyA9IDEwMCkKYGBgCgoKIyMgRGVhbGluZyB3aXRoIFNvbWUgSXNzdWVzCgpUaGVyZSBhcmUgYSBsb3Qgb2YgY291bnRyaWVzIHRoYXQgaGF2ZSBubyBkYXRhIGZvciB0aGUgcmVnaW9ucywgYnV0IGhhdmUgbm9uIHplcm8gaXJycGVyYy9mcmFjIHdoaWNoIEkgd2lsbCB1c2UgaW4gZnVydGhlciBhbmFseXNpcywgc28gd2UgbmVlZCB0byByZXBsYWNlIHRoZSByZWdpb25zLiAKCmBgYHtyfQojdmlldyB3aGljaCBjb3VudHJpZXMgZG9uJ3QgaGF2ZSByZWdpb25zIGJ1dCBoYXZlIG5vbiB6ZXJvIGlycnByZWMKbmFfcmVnaW9ucyA8LSBhZWlbaXMubmEoYWVpJGZvdXJfcmVnaW9ucyksXQoKI0FydWJhCmFlaSA8LSBhZWkgJT4lCiAgbXV0YXRlKGZvdXJfcmVnaW9ucyA9IHJlcGxhY2UoZm91cl9yZWdpb25zLCBJU08gPT0gJ0FCVycsICdhbWVyaWNhcycpLCAKICAgICAgICAgc2l4X3JlZ2lvbnMgPSByZXBsYWNlKHNpeF9yZWdpb25zLCBJU08gPT0gJ0FCVycsICdhbWVyaWNhJyksIAogICAgICAgICBlaWdodF9yZWdpb25zID0gcmVwbGFjZShlaWdodF9yZWdpb25zLCBJU08gPT0gJ0FCVycsICdhbWVyaWNhX25vcnRoJykpICU+JQojYW1lcmljYW4gc2Ftb2EKICBtdXRhdGUoZm91cl9yZWdpb25zID0gcmVwbGFjZShmb3VyX3JlZ2lvbnMsSVNPID09ICdBU00nLCAnYXNpYScpLCAKICAgICAgICAgc2l4X3JlZ2lvbnMgPSByZXBsYWNlKHNpeF9yZWdpb25zLElTTyA9PSAnQVNNJywgJ2Vhc3RfYXNpYV9wYWNpZmljJyksIAogICAgICAgICBlaWdodF9yZWdpb25zID0gcmVwbGFjZShlaWdodF9yZWdpb25zLElTTyA9PSAnQVNNJywgJ2Vhc3RfYXNpYV9wYWNpZmljJykpICU+JQojYmVybXVkYQogIG11dGF0ZShmb3VyX3JlZ2lvbnMgPSByZXBsYWNlKGZvdXJfcmVnaW9ucyxJU08gPT0gJ0JNVScsICdhbWVyaWNhcycpLCAKICAgICAgICAgc2l4X3JlZ2lvbnMgPSByZXBsYWNlKHNpeF9yZWdpb25zLElTTyA9PSAnQk1VJywgJ2FtZXJpY2EnKSwgCiAgICAgICAgIGVpZ2h0X3JlZ2lvbnMgPSByZXBsYWNlKGVpZ2h0X3JlZ2lvbnMsSVNPID09ICdCTVUnLCAnYW1lcmljYV9ub3J0aCcpKSAlPiUgCiNjb3RlIGQnaXZvaXJlCiAgbXV0YXRlKGZvdXJfcmVnaW9ucyA9IHJlcGxhY2UoZm91cl9yZWdpb25zLElTTyA9PSAnQ0lWJywgJ2FmcmljYScpLCAKICAgICAgICAgc2l4X3JlZ2lvbnMgPSByZXBsYWNlKHNpeF9yZWdpb25zLElTTyA9PSAnQ0lWJywgJ3N1Yl9zYWhhcmFuX2FmcmljYScpLCAKICAgICAgICAgZWlnaHRfcmVnaW9ucyA9IHJlcGxhY2UoZWlnaHRfcmVnaW9ucyxJU08gPT0gJ0NJVicsICdhZnJpY2Ffc3ViX3NhaGFyYW4nKSkgJT4lIAojZGVtb2NyYXRpYyByZXB1YmxpYyBvZiBjb25nbwogIG11dGF0ZShmb3VyX3JlZ2lvbnMgPSByZXBsYWNlKGZvdXJfcmVnaW9ucyxJU08gPT0gJ0NPRCcsICdhZnJpY2EnKSwgCiAgICAgICAgIHNpeF9yZWdpb25zID0gcmVwbGFjZShzaXhfcmVnaW9ucyxJU08gPT0gJ0NPRCcsICdzdWJfc2FoYXJhbl9hZnJpY2EnKSwgCiAgICAgICAgIGVpZ2h0X3JlZ2lvbnMgPSByZXBsYWNlKGVpZ2h0X3JlZ2lvbnMsSVNPID09ICdDT0QnLCAnYWZyaWNhX3N1Yl9zYWhhcmFuJykpICU+JSAKI3JlcHVibGljIG9mIGNvbmdvCiAgbXV0YXRlKGZvdXJfcmVnaW9ucyA9IHJlcGxhY2UoZm91cl9yZWdpb25zLElTTyA9PSAnQ09HJywgJ2FmcmljYScpLCAKICAgICAgICAgc2l4X3JlZ2lvbnMgPSByZXBsYWNlKHNpeF9yZWdpb25zLElTTyA9PSAnQ09HJywgJ3N1Yl9zYWhhcmFuX2FmcmljYScpLCAKICAgICAgICAgZWlnaHRfcmVnaW9ucyA9IHJlcGxhY2UoZWlnaHRfcmVnaW9ucyxJU08gPT0gJ0NPRycsICdhZnJpY2Ffc3ViX3NhaGFyYW4nKSkgJT4lIAojY2F5bWFuIGlzbGFuZHMKICBtdXRhdGUoZm91cl9yZWdpb25zID0gcmVwbGFjZShmb3VyX3JlZ2lvbnMsSVNPID09ICdDWU0nLCAnYW1lcmljYXMnKSwgCiAgICAgICAgIHNpeF9yZWdpb25zID0gcmVwbGFjZShzaXhfcmVnaW9ucyxJU08gPT0gJ0NZTScsICdhbWVyaWNhJyksIAogICAgICAgICBlaWdodF9yZWdpb25zID0gcmVwbGFjZShlaWdodF9yZWdpb25zLElTTyA9PSAnQ1lNJywgJ2FtZXJpY2Ffbm9ydGgnKSkgJT4lCiNGYXJvZSBpc2xhbmRzCiAgbXV0YXRlKGZvdXJfcmVnaW9ucyA9IHJlcGxhY2UoZm91cl9yZWdpb25zLElTTyA9PSAnRlJPJywgJ2V1cm9wZScpLCAKICAgICAgICAgc2l4X3JlZ2lvbnMgPSByZXBsYWNlKHNpeF9yZWdpb25zLElTTyA9PSAnRlJPJywgJ2V1cm9wZV9jZW50cmFsX2FzaWEnKSwgCiAgICAgICAgIGVpZ2h0X3JlZ2lvbnMgPSByZXBsYWNlKGVpZ2h0X3JlZ2lvbnMsSVNPID09ICdGUk8nLCAnZXVyb3BlX3dlc3QnKSkgJT4lCiNtaWNyb25lc2lhCiAgbXV0YXRlKGZvdXJfcmVnaW9ucyA9IHJlcGxhY2UoZm91cl9yZWdpb25zLElTTyA9PSAnRlNNJywgJ2FzaWEnKSwgCiAgICAgICAgIHNpeF9yZWdpb25zID0gcmVwbGFjZShzaXhfcmVnaW9ucyxJU08gPT0gJ0ZTTScsICdlYXN0X2FzaWFfcGFjaWZpYycpLCAKICAgICAgICAgZWlnaHRfcmVnaW9ucyA9IHJlcGxhY2UoZWlnaHRfcmVnaW9ucyxJU08gPT0gJ0ZTTScsICdlYXN0X2FzaWFfcGFjaWZpYycpKSAlPiUKI2dpYnJhbHRhcgogIG11dGF0ZShmb3VyX3JlZ2lvbnMgPSByZXBsYWNlKGZvdXJfcmVnaW9ucyxJU08gPT0gJ0dJQicsICdldXJvcGUnKSwgCiAgICAgICAgIHNpeF9yZWdpb25zID0gcmVwbGFjZShzaXhfcmVnaW9ucyxJU08gPT0gJ0dJQicsICdldXJvcGVfY2VudHJhbF9hc2lhJyksIAogICAgICAgICBlaWdodF9yZWdpb25zID0gcmVwbGFjZShlaWdodF9yZWdpb25zLElTTyA9PSAnR0lCJywgJ2V1cm9wZV93ZXN0JykpICU+JQojR3VhZGVsb3VwZQogIG11dGF0ZShmb3VyX3JlZ2lvbnMgPSByZXBsYWNlKGZvdXJfcmVnaW9ucyxJU08gPT0gJ0dMUCcsICdhbWVyaWNhcycpLCAKICAgICAgICAgc2l4X3JlZ2lvbnMgPSByZXBsYWNlKHNpeF9yZWdpb25zLElTTyA9PSAnR0xQJywgJ2FtZXJpY2EnKSwgCiAgICAgICAgIGVpZ2h0X3JlZ2lvbnMgPSByZXBsYWNlKGVpZ2h0X3JlZ2lvbnMsSVNPID09ICdHTFAnLCAnYW1lcmljYV9ub3J0aCcpKSAlPiUKI2dyZWVubGFuZAogIG11dGF0ZShmb3VyX3JlZ2lvbnMgPSByZXBsYWNlKGZvdXJfcmVnaW9ucyxJU08gPT0gJ0dSTCcsICdldXJvcGUnKSwgCiAgICAgICAgIHNpeF9yZWdpb25zID0gcmVwbGFjZShzaXhfcmVnaW9ucyxJU08gPT0gJ0dSTCcsICdldXJvcGVfY2VudHJhbF9hc2lhJyksIAogICAgICAgICBlaWdodF9yZWdpb25zID0gcmVwbGFjZShlaWdodF9yZWdpb25zLElTTyA9PSAnR1JMJywgJ2V1cm9wZV93ZXN0JykpICU+JQojZnJlbmNoIEd1aWFuYSAKICBtdXRhdGUoZm91cl9yZWdpb25zID0gcmVwbGFjZShmb3VyX3JlZ2lvbnMsSVNPID09ICdHVUYnLCAnYW1lcmljYXMnKSwgCiAgICAgICAgIHNpeF9yZWdpb25zID0gcmVwbGFjZShzaXhfcmVnaW9ucyxJU08gPT0gJ0dVRicsICdhbWVyaWNhJyksIAogICAgICAgICBlaWdodF9yZWdpb25zID0gcmVwbGFjZShlaWdodF9yZWdpb25zLElTTyA9PSAnR1VGJywgJ2FtZXJpY2Ffc291dGgnKSkgJT4lCiNndWFtCiAgbXV0YXRlKGZvdXJfcmVnaW9ucyA9IHJlcGxhY2UoZm91cl9yZWdpb25zLElTTyA9PSAnR1VNJywgJ2FzaWEnKSwgCiAgICAgICAgIHNpeF9yZWdpb25zID0gcmVwbGFjZShzaXhfcmVnaW9ucyxJU08gPT0gJ0dVTScsICdlYXN0X2FzaWFfcGFjaWZpYycpLCAKICAgICAgICAgZWlnaHRfcmVnaW9ucyA9IHJlcGxhY2UoZWlnaHRfcmVnaW9ucyxJU08gPT0gJ0dVTScsICdlYXN0X2FzaWFfcGFjaWZpYycpKSAlPiUKI0t5cmd5enN0YW4KICBtdXRhdGUoZm91cl9yZWdpb25zID0gcmVwbGFjZShmb3VyX3JlZ2lvbnMsSVNPID09ICdLR1onLCAnYXNpYScpLCAKICAgICAgICAgc2l4X3JlZ2lvbnMgPSByZXBsYWNlKHNpeF9yZWdpb25zLElTTyA9PSAnS0daJywgJ2V1cm9wZV9jZW50cmFsX2FzaWEnKSwgCiAgICAgICAgIGVpZ2h0X3JlZ2lvbnMgPSByZXBsYWNlKGVpZ2h0X3JlZ2lvbnMsSVNPID09ICdLR1onLCAnYXNpYV93ZXN0JykpICU+JQojbGFvcwogIG11dGF0ZShmb3VyX3JlZ2lvbnMgPSByZXBsYWNlKGZvdXJfcmVnaW9ucyxJU08gPT0gJ0xBTycsICdhc2lhJyksIAogICAgICAgICBzaXhfcmVnaW9ucyA9IHJlcGxhY2Uoc2l4X3JlZ2lvbnMsSVNPID09ICdMQU8nLCAnZWFzdF9hc2lhX3BhY2lmaWMnKSwgCiAgICAgICAgIGVpZ2h0X3JlZ2lvbnMgPSByZXBsYWNlKGVpZ2h0X3JlZ2lvbnMsSVNPID09ICdMQU8nLCAnZWFzdF9hc2lhX3BhY2lmaWMnKSkgJT4lCiNNYWNlZG9uaWEKICBtdXRhdGUoZm91cl9yZWdpb25zID0gcmVwbGFjZShmb3VyX3JlZ2lvbnMsSVNPID09ICdNS0QnLCAnZXVyb3BlJyksIAogICAgICAgICBzaXhfcmVnaW9ucyA9IHJlcGxhY2Uoc2l4X3JlZ2lvbnMsSVNPID09ICdNS0QnLCAnZXVyb3BlX2NlbnRyYWxfYXNpYScpLCAKICAgICAgICAgZWlnaHRfcmVnaW9ucyA9IHJlcGxhY2UoZWlnaHRfcmVnaW9ucyxJU08gPT0gJ01LRCcsICdldXJvcGVfZWFzdCcpKSAlPiUKI01hcnRpbmlxdWUgCiAgbXV0YXRlKGZvdXJfcmVnaW9ucyA9IHJlcGxhY2UoZm91cl9yZWdpb25zLElTTyA9PSAnTVRRJywgJ2FtZXJpY2FzJyksIAogICAgICAgICBzaXhfcmVnaW9ucyA9IHJlcGxhY2Uoc2l4X3JlZ2lvbnMsSVNPID09ICdNVFEnLCAnYW1lcmljYScpLCAKICAgICAgICAgZWlnaHRfcmVnaW9ucyA9IHJlcGxhY2UoZWlnaHRfcmVnaW9ucyxJU08gPT0gJ01UUScsICdhbWVyaWNhX25vcnRoJykpICU+JQojbmV3IGNhbGVkb25pYQogIG11dGF0ZShmb3VyX3JlZ2lvbnMgPSByZXBsYWNlKGZvdXJfcmVnaW9ucyxJU08gPT0gJ05DTCcsICdhc2lhJyksIAogICAgICAgICBzaXhfcmVnaW9ucyA9IHJlcGxhY2Uoc2l4X3JlZ2lvbnMsSVNPID09ICdOQ0wnLCAnZWFzdF9hc2lhX3BhY2lmaWMnKSwgCiAgICAgICAgIGVpZ2h0X3JlZ2lvbnMgPSByZXBsYWNlKGVpZ2h0X3JlZ2lvbnMsSVNPID09ICdOQ0wnLCAnZWFzdF9hc2lhX3BhY2lmaWMnKSkgJT4lCiNwdWVydG8gcmljbwogbXV0YXRlKGZvdXJfcmVnaW9ucyA9IHJlcGxhY2UoZm91cl9yZWdpb25zLElTTyA9PSAnUFJJJywgJ2FtZXJpY2FzJyksIAogICAgICAgICBzaXhfcmVnaW9ucyA9IHJlcGxhY2Uoc2l4X3JlZ2lvbnMsSVNPID09ICdQUkknLCAnYW1lcmljYScpLCAKICAgICAgICAgZWlnaHRfcmVnaW9ucyA9IHJlcGxhY2UoZWlnaHRfcmVnaW9ucyxJU08gPT0gJ1BSSScsICdhbWVyaWNhX25vcnRoJykpICU+JQojUGFsZXN0aW5lIChXZXN0IEJhbmsgKyBHYXphIHN0cmlwKQogbXV0YXRlKGZvdXJfcmVnaW9ucyA9IHJlcGxhY2UoZm91cl9yZWdpb25zLElTTyA9PSAnUFNFJywgJ2FzaWEnKSwgCiAgICAgICAgIHNpeF9yZWdpb25zID0gcmVwbGFjZShzaXhfcmVnaW9ucyxJU08gPT0gJ1BTRScsICdtaWRkbGVfZWFzdF9ub3J0aF9hZnJpY2EnKSwgCiAgICAgICAgIGVpZ2h0X3JlZ2lvbnMgPSByZXBsYWNlKGVpZ2h0X3JlZ2lvbnMsSVNPID09ICdQU0UnLCAnYXNpYV93ZXN0JykpICU+JQojZnJlbmNoIFBvbHluZXNpYQogIG11dGF0ZShmb3VyX3JlZ2lvbnMgPSByZXBsYWNlKGZvdXJfcmVnaW9ucyxJU08gPT0gJ1BZRicsICdhc2lhJyksIAogICAgICAgICBzaXhfcmVnaW9ucyA9IHJlcGxhY2Uoc2l4X3JlZ2lvbnMsSVNPID09ICdQWUYnLCAnZWFzdF9hc2lhX3BhY2lmaWMnKSwgCiAgICAgICAgIGVpZ2h0X3JlZ2lvbnMgPSByZXBsYWNlKGVpZ2h0X3JlZ2lvbnMsSVNPID09ICdQWUYnLCAnZWFzdF9hc2lhX3BhY2lmaWMnKSkgJT4lCiNSZXVuaW9uCiAgbXV0YXRlKGZvdXJfcmVnaW9ucyA9IHJlcGxhY2UoZm91cl9yZWdpb25zLElTTyA9PSAnUkVVJywgJ2FmcmljYScpLCAKICAgICAgICAgc2l4X3JlZ2lvbnMgPSByZXBsYWNlKHNpeF9yZWdpb25zLElTTyA9PSAnUkVVJywgJ3N1Yl9zYWhhcmFuX2FmcmljYScpLCAKICAgICAgICAgZWlnaHRfcmVnaW9ucyA9IHJlcGxhY2UoZWlnaHRfcmVnaW9ucyxJU08gPT0gJ1JFVScsICdhZnJpY2Ffc3ViX3NhaGFyYW4nKSkgJT4lCiNTZXJiaWEsIE1vbnRlbmVncm8sIEtvc292bwogIG11dGF0ZShmb3VyX3JlZ2lvbnMgPSByZXBsYWNlKGZvdXJfcmVnaW9ucyxJU08gPT0gJ1NNSycsICdldXJvcGUnKSwgCiAgICAgICAgIHNpeF9yZWdpb25zID0gcmVwbGFjZShzaXhfcmVnaW9ucyxJU08gPT0gJ1NNSycsICdldXJvcGVfY2VudHJhbF9hc2lhJyksIAogICAgICAgICBlaWdodF9yZWdpb25zID0gcmVwbGFjZShlaWdodF9yZWdpb25zLElTTyA9PSAnU01LJywgJ2V1cm9wZV9lYXN0JykpICU+JQojU2xvdmFraWEKICBtdXRhdGUoZm91cl9yZWdpb25zID0gcmVwbGFjZShmb3VyX3JlZ2lvbnMsSVNPID09ICdTVksnLCAnZXVyb3BlJyksIAogICAgICAgICBzaXhfcmVnaW9ucyA9IHJlcGxhY2Uoc2l4X3JlZ2lvbnMsSVNPID09ICdTVksnLCAnZXVyb3BlX2NlbnRyYWxfYXNpYScpLCAKICAgICAgICAgZWlnaHRfcmVnaW9ucyA9IHJlcGxhY2UoZWlnaHRfcmVnaW9ucyxJU08gPT0gJ1NWSycsICdldXJvcGVfZWFzdCcpKSAlPiUKI1R1cmtzIGFuZCBDYWljb3MgSXNsYW5kcwogIG11dGF0ZShmb3VyX3JlZ2lvbnMgPSByZXBsYWNlKGZvdXJfcmVnaW9ucyxJU08gPT0gJ1RDQScsICdhbWVyaWNhcycpLCAKICAgICAgICAgc2l4X3JlZ2lvbnMgPSByZXBsYWNlKHNpeF9yZWdpb25zLElTTyA9PSAnVENBJywgJ2FtZXJpY2EnKSwgCiAgICAgICAgIGVpZ2h0X3JlZ2lvbnMgPSByZXBsYWNlKGVpZ2h0X3JlZ2lvbnMsSVNPID09ICdUQ0EnLCAnYW1lcmljYV9ub3J0aCcpKSAlPiUKI0Vhc3QgVGltb3IKICBtdXRhdGUoZm91cl9yZWdpb25zID0gcmVwbGFjZShmb3VyX3JlZ2lvbnMsSVNPID09ICdUTFMnLCAnYXNpYScpLCAKICAgICAgICAgc2l4X3JlZ2lvbnMgPSByZXBsYWNlKHNpeF9yZWdpb25zLElTTyA9PSAnVExTJywgJ2Vhc3RfYXNpYV9wYWNpZmljJyksIAogICAgICAgICBlaWdodF9yZWdpb25zID0gcmVwbGFjZShlaWdodF9yZWdpb25zLElTTyA9PSAnVExTJywgJ2Vhc3RfYXNpYV9wYWNpZmljJykpICU+JQojdGFpd2FuCiAgbXV0YXRlKGZvdXJfcmVnaW9ucyA9IHJlcGxhY2UoZm91cl9yZWdpb25zLElTTyA9PSAnVFdOJywgJ2FzaWEnKSwgCiAgICAgICAgIHNpeF9yZWdpb25zID0gcmVwbGFjZShzaXhfcmVnaW9ucyxJU08gPT0gJ1RXTicsICdlYXN0X2FzaWFfcGFjaWZpYycpLCAKICAgICAgICAgZWlnaHRfcmVnaW9ucyA9IHJlcGxhY2UoZWlnaHRfcmVnaW9ucyxJU08gPT0gJ1RXTicsICdlYXN0X2FzaWFfcGFjaWZpYycpKSAlPiUKI0JyaXRpc2ggdmlyZ2luIElzbGFuZHMKICBtdXRhdGUoZm91cl9yZWdpb25zID0gcmVwbGFjZShmb3VyX3JlZ2lvbnMsSVNPID09ICdWR0InLCAnYW1lcmljYXMnKSwgCiAgICAgICAgIHNpeF9yZWdpb25zID0gcmVwbGFjZShzaXhfcmVnaW9ucyxJU08gPT0gJ1ZHQicsICdhbWVyaWNhJyksIAogICAgICAgICBlaWdodF9yZWdpb25zID0gcmVwbGFjZShlaWdodF9yZWdpb25zLElTTyA9PSAnVkdCJywgJ2FtZXJpY2Ffbm9ydGgnKSkgJT4lCiNVUyBWaXJnaW4gSXNsYW5kcwogIG11dGF0ZShmb3VyX3JlZ2lvbnMgPSByZXBsYWNlKGZvdXJfcmVnaW9ucyxJU08gPT0gJ1ZJUicsICdhbWVyaWNhcycpLCAKICAgICAgICAgc2l4X3JlZ2lvbnMgPSByZXBsYWNlKHNpeF9yZWdpb25zLElTTyA9PSAnVklSJywgJ2FtZXJpY2EnKSwgCiAgICAgICAgIGVpZ2h0X3JlZ2lvbnMgPSByZXBsYWNlKGVpZ2h0X3JlZ2lvbnMsIElTTyA9PSAnVklSJywgJ2FtZXJpY2Ffbm9ydGgnKSkgCgpgYGAKTmV4dCB0aW1lIEknbGwgd3JpdGUgYSBmdW5jdGlvbi4KClRoZXJlIGFyZSBhbHNvIGEgbG90IG9mIGNvdW50cmllcyB0aGF0IGhhdmUgTkEgdmFsdWVzIGZvciB0aGVpciBpbmNvbWUgb3IgcG9wdWxhdGlvbi4gVGFrZSBhIHBlZWsgaGVyZS4KCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxvdGFuYXMgPC0gIGFlaVtyb3dTdW1zKGlzLm5hKGFlaSkpID4gMCxdCmxvdGFuYXMgJT4lIAogIGdyb3VwX2J5KGNvdW50cnkpICU+JSAKICBzZWxlY3QoaW5jb21lLCBwb3B1bGF0aW9uKSAlPiUgIAogIHN1bW1hcmlzZV9hbGwoZnVucyhzdW0oaXMubmEoLikpKSkKCgpgYGAKCgpUaGUgY291bnRyaWVzIHRoYXQgZG9uJ3QgaGF2ZSBpbmNvbWUgYWxzbyBkb24ndCBoYXZlIHBvcHVsYXRpb24sIHNvIGFzIGxlYXN0IEkgYW0gY29uc2lzdGVudCBpbiBteSBtaXNzaW5nIGRhdGEuIEkgaGF2ZSB0byBtb3ZlIG9uIHNvIEkgd2lsbCBqdXN0IGxlYXZlIHRoaXMgaGVyZSBmb3IgYSBtaW51dGUuIFBlcmhhcHMgbGF0ZXIgd2Ugc2hvdWxkIGZpbGwgdGhlc2UgdmFyaWFibGVzLiAgCgoKCiMjIFByZWNpcGl0YXRpb24KCkFnYWluLCBwcmVjaXBpdGF0aW9uIGlzIHRyYW5zbGF0ZWQgb3V0cHV0IGZyb20gTFBKbUwuIFByZWNpcGl0YXRpb24gd2FzIGNob3NlbiBiZWNhdXNlIGl0IGNvdWxkIGJlIHN1bW1lZCBhY3Jvc3MgY291bnRyaWVzLCBhcyBvdGhlciBkYXRhIGNvdWxkIG5vdCAobGlrZSBkaXNjaGFyZ2Ugb3IgRVQpLiBJIGhhdmUgc3VtbWVkIHRoZSBwcmVjaXBpdGF0aW9uIGJ5IGNvdW50cnkgYW5kIHllYXIuIEkgYW0gbm90IHN1cmUgd2hldGhlciBJIHNob3VsZCBzY2FsZSBvciBzdGFuZGFyZGl6ZSBwcmVjaXAsIEkgd2lsbCBkbyBhbGwgdGhlIHBvc3NpYmxlIGNvbWJpbmF0aW9ucyBhdCB0aGUgbW9tZW50LiAKYGBge3IgUHJlY2lwIE1hbmlwdWxhdGlvbiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KI3ByZWNpcGl0YXRpb24KI2NmdGFuZHByZWNpcCBpcyBhIHNjcmlwdCB3aXRoIGFsbCB0aGUgZ3JpZCBjZWxsIHZhbHVlcy4gCmNmdGFuZHByZWNpcCA8LSByZWFkLmNzdignL1ZvbHVtZXMvUmFjaGVsRXh0ZXJuYWwvVGhlc2lzL1RoZXNpcy9EYXRhL2NmdF9hbmRfcHJlY2lwZGF0YS5jc3YnKQpjZnRhbmRwcmVjaXAkSVNPIDwtIGFzLmZhY3RvcihjZnRhbmRwcmVjaXAkSVNPKQpjZnRhbmRwcmVjaXAgPC0gY2Z0YW5kcHJlY2lwWywgLWMoMSldICNyZW1vdmUgaWQgY29sCmNmdGFuZHByZWNpcCA8LSBzdWJzZXQoY2Z0YW5kcHJlY2lwLCB5ZWFyID49IDE5NjApCgojbG9nIGFuZCBzY2FsZQpwcmVjaXAgPC0gCiAgY2Z0YW5kcHJlY2lwICU+JSAKICBzZWxlY3QoSVNPLCB5ZWFyLCBwcmVjaXBtbSkgJT4lIAogIGdyb3VwX2J5KElTTywgeWVhcikgJT4lIAogIHN1bW1hcmlzZShwcmVjaXB0b3QgPSAoc3VtKHByZWNpcG1tKSkpICU+JSAjc3VtIGdyaWQgY2VsbHMgYnkgSVNPIGFuZCB5ZWFyCiAgbXV0YXRlKHByZWNpcF9zYyA9IHByZWNpcHRvdC9tYXgocHJlY2lwdG90KSkgJT4lIAogIG11dGF0ZShwcmVjaXBfc3RkID0gcHJlY2lwdG90L21lYW4ocHJlY2lwdG90KSkgJT4lIAogIG11dGF0ZShsb2dfcHJlY2lwID0gbG9nKHByZWNpcHRvdCsxKSkgJT4lICMxIGlzIGFkZGVkIGhlcmUgdG8gcHJldmVudCAtSW5mCiAgbXV0YXRlKGxvZ19wcmVjaXBfc2MgPSBsb2dfcHJlY2lwL21heChsb2dfcHJlY2lwKSkgJT4lIAogIG11dGF0ZShsb2dfcHJlY2lwX3N0ZCA9IGxvZ19wcmVjaXAvbWVhbihsb2dfcHJlY2lwKSkKCiNtZXJnZQphZWkgPC0gbWVyZ2UoYWVpLCBwcmVjaXAsIGJ5ID0gYygiSVNPIiwgInllYXIiKSwgYWxsLnggPSBUUlVFKQpybShwcmVjaXApCmBgYAoKQW5kIHNvbWUgaGlzdG9ncmFtcyB0byBjaGVjayBvdXQgdGhlIHNjYWxlZC9zdGFuZGFyZGl6ZWQgZGF0YS4gCmBgYHtyIFByZWNpcCBIaXN0c30KaGlzdChhZWkkcHJlY2lwdG90LCBicmVha3MgPSAxMDApCmhpc3QoYWVpJHByZWNpcF9zYywgYnJlYWtzID0gMTAwKQpoaXN0KGFlaSRwcmVjaXBfc3RkLCBicmVha3MgPSAxMDApCmhpc3QoYWVpJGxvZ19wcmVjaXAsIGJyZWFrcyA9IDEwMCkKaGlzdChhZWkkbG9nX3ByZWNpcF9zYywgYnJlYWtzID0gMTAwKQpoaXN0KGFlaSRsb2dfcHJlY2lwX3N0ZCwgYnJlYWtzID0gMTAwKQpgYGAKCgojIyBDcm9wIEZyYWN0aW9uCgpVZmYuIFRoZW4gY29tZXMgY3JvcCBmcmFjdGlvbi4gQXMgbWVudGlvbmVkIGFib3ZlIGluZGl2aWR1YWwgY3JvcCBmcmFjdGlvbiBwZXIgZ3JpZCBjZWxsIGlzIG11bHRpcGxpZWQgYnkgcmVzcGVjdGl2ZSBncmlkIGNlbGwgYXJlYSwgc3VtbWVkIG9uIGEgY291bnRyeSBsZXZlbCBnaXZpbmcgaGEgb2YgZWFjaCBjcm9wIGdyb3duIHBlciBjb3VudHJ5LiBUaGlzIHdhcyB0aGVuIGRpdmlkZWQgYnkgdG90YWwgYXJlYSBvZiB0aGUgY291bnRyeSB0byBhY2hpZXZlIHRoZSAlIGFyZWEgb2NjdXBpZWQgYnkgYSBjZXJ0YWluIGNyb3AgcGVyIGNvdW50cnkuCmBgYHtyIENGVCBtYW5pcHVsYXRpb24sIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiNwdWxsIGNmdCBmcmFjIG91dHRhIGhlcmUKY2Z0IDwtIAogIGNmdGFuZHByZWNpcCAlPiUgCiAgc2VsZWN0KC1jKDQpKSAlPiUgI3JlbW92aW5nIHByZWNpcAogIG11dGF0ZV9lYWNoKGZ1bnMoLipjZWxsYXJlYW0yKSwgYyg0OjM1KSkgJT4lICNtdWx0aXBseSBhbGwgZnJhY3Rpb25zIHdpdGggdGhlIGNlbGwgYXJlYQogIGdyb3VwX2J5KElTTywgeWVhcikgJT4lICNncm91cCBpbiB0byBjb3VudHJ5IGFuZCB5ZWFyCiAgc3VtbWFyaXNlX2VhY2goZnVucyhzdW0pKSAlPiUgI3Rha2UgY29sIHN1bXMgZm9yIGVhY2ggY3JvcAogIG11dGF0ZShhY3Jvc3MoYygzOjM0KSwgLmZucyA9IH4uL2NlbGxhcmVhbTIpKSAjZGl2aWRlIGNvbCBzdW1zIGJ5IHRvdGFsIGNvdW50cnkgYXJlYSAKCiNyZW1vdmluZyBjYXRlZ29yaWVzIHdpdGggMCAodGhlIGJpb2Z1ZWxzIGFuZCBzdWNoKQpjZnQgPC0gY2Z0WywgLWMoMTgsIDE5LCAyNiwgMzQsIDM1KV0KCiNhbmQgYSBtZXJnZQphZWkgPC0gbWVyZ2UoYWVpLCBjZnQsIGJ5ID0gYygiSVNPIiwgInllYXIiKSwgYWxsLnggPSBUUlVFKQpybShjZnQsIGNmdGFuZHByZWNpcCkKYGBgCgpJZGsgaG93IHRvIHNob3cgdGhlIGRhdGEgaGVyZS4gQW55IGlkZWFzIG9uIHJlcHJlc2VudGF0aW9uIHdvdWxkIGJlIGhlbHBmdWwgaGVyZS4gCgojIyBUb3BvZ3JhcGhpY2FsCgpUb3BvZ3JhcGhpY2FsIGRhdGEgaXMgcmVwcmVzZW50ZWQgaGVyZSBieSB0aGUgZGF0YSBzZXQgZnJvbSBAcmlsZXlUZXJyYWluUnVnZ2VkbmVzc0luZGV4MTk5OSBhbmQgaXMgY29udmllbnRseSBhdmFpbGFibGUgdGhyb3VnaCB0aGUgYGxpYnJhcnkocmV0aGlua2luZylgIGZyb20gQG1jZWxyZWF0aFN0YXRpc3RpY2FsUmV0aGlua2luZ0JheWVzaWFuMjAxNS4gSXQgcHJvdmlkZXMgYSBydWdnZWRuZXNzIGZhY3RvciBmb3IgZWFjaCBjb3VudHJ5LiAKCmBgYHtyfQojcnVnZ2VkCmRhdGEoInJ1Z2dlZCIpCnJ1ZyA8LSBydWdnZWQgJT4lIHNlbGVjdChjKCJpc29jb2RlIiwgInJ1Z2dlZCIpKSAKY29sbmFtZXMocnVnKSA8LSBjKCJJU08iLCAicnVnZ2VkIikKI3NjYWxpbmcKcnVnJHJ1Z2dlZF9zYyA8LSBydWckcnVnZ2VkIC8gbWF4KHJ1ZyRydWdnZWQpCiNtZXJnZQphZWkgPC0gbWVyZ2UoYWVpLCBydWcsIGJ5ID0gIklTTyIsIGFsbC54ID0gVFJVRSkKcm0ocnVnLCBydWdnZWQpCgoKYGBgCgpgYGB7cn0KaGlzdChhZWkkcnVnZ2VkX3NjLCBicmVha3MgPSAxMDApCmBgYAoKCioqKiAgIAoKCgojIFRpbWUgU2VyaWVzIEV2b2x1dGlvbiBvZiBDb3VudHJ5IExldmVsIFRhcmdldCBWYXJpYWJsZQoKT2ssIHNvIGxldHMgcGVlayBhdCBob3cgdGhpbmdzIGNoYW5nZSBvdmVyIHRpbWUuIEhlcmUgaXMgYSBncmFwaCBvZiBwZXJjZW50YWdlIG9mIGNvdW50cnkgYXJlYSBlcXVpcHBlZCBmb3IgaXJyaWdhdGlvbiBmcm9tIDE5NjAgLSAyMDA1LgoKYGBge3IgSXJyaWdhdGVkIFRvdGFscyBHcmFwaCwgd2FybmluZz1GQUxTRX0KCnBpcnJmcmFjIDwtCiAgZ2dwbG90KGRhdGEgPSBzdWJzZXQoYWVpLCAhaXMubmEoaXJycGVyYykpLCAKICAgICAgICAgbWFwcGluZyA9IGFlcyh4PXllYXIsIHk9IGlycnBlcmMsIGdyb3VwID0gY291bnRyeSwgY29sb3IgPSBzaXhfcmVnaW9ucykpICsKICBnZW9tX2xpbmUoKSArCiAgc2NhbGVfeF9jb250aW51b3VzKCkgKwogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCkpIAoKI3J1biB0aGlzIHNlcGFyYXRlbHksIG90aGVyd2lzZSB0aGUgcGxvdGx5IHBhcnQgZG9lc24ndCB3b3JrLgpnZ3Bsb3RseShwaXJyZnJhYykKCgpgYGAKQWx0aG91Z2ggdGhpcyBncmFwaCBoYXMgYSBsb3Qgb2YgY291bnRyaWVzIGFuZCBjYW4gZ2V0IHF1aXRlIG1lc3N5LCBzb21lIGdlbmVyYWwgdHJlbmRzIGFwcGVhci4gU291dGggQXNpYW4gY291bnRyaWVzIHNlZW0gdG8gaGF2ZSBoaWdoIHBlcmNlbnRhZ2VzIG9mIGlycmlnYXRlZCBhcmVhIHBlciB0b3RhbCBsYW5kIGFyZWEgKGlycmlnYXRpb24gcGVyY2VudGFnZSkuIFRoZW4gc2VlbWluZ2x5IGZvbGxvd2VkIGJ5IEVhc3QgQXNpYW4gYW5kIEV1cm9wZWFuIGNvdW50cmllcy4gQWZyaWNhIGFuZCB0aGUgTWlkZGxlIEVhc3QgZG8gbm90IHNlZW0gdG8gYmUgaXJyaWdhdGVkIGFzIG11Y2guIEJlIGF3YXJlIHRoYXQgeW91IGNhbiB0aGVzZSBncmFwaHMgYXJlIGludGVyYWN0aXZlLCB5b3UgbWF5IHpvb20sIHBhbiBvciBjbGljayBvbiB0aGUgbGVnZW5kIHRvIGlzb2xhdGUgdGhlIHJlZ2lvbnMuIEFsdGhvdWdoLCBhIHJlZ2lvbmFsIGJyZWFrZG93biBmb2xsb3dzLgoKCgojIyBTdWItU2FoYXJhbiBBZnJpY2EKICAKYGBge3IgQWZyaWNhIElycmlnYXRlZCBUb3RhbHMgR3JhcGgsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnBpcnJzc0FGIDwtCiAgZ2dwbG90KGRhdGEgPSBzdWJzZXQoYWVpLCBzaXhfcmVnaW9ucyA9PSAic3ViX3NhaGFyYW5fYWZyaWNhIiksIAogICAgICAgICBtYXBwaW5nID0gYWVzKHg9eWVhciwgeT0gaXJycGVyYywgY29sb3IgPSBjb3VudHJ5KSkgKwogIGdlb21fbGluZSgpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoKSArCiAgdGhlbWUocGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSkgCgojcnVuIHRoaXMgc2VwYXJhdGVseSwgb3RoZXJ3aXNlIHRoZSBwbG90bHkgcGFydCBkb2Vzbid0IHdvcmsuCmdncGxvdGx5KHBpcnJzc0FGKQpgYGAKICAKSW4gZ2VuZXJhbCwgQWZyaWNhIGhhcyBsb3cgbGV2ZWxzIG9mIGlycmlnYXRlZCBhcmVhLiBTd2F6aWxhbmQsIFNhbyBUb21lIGFuZCBQcmluY2lwZSwgUmV1bmlvbiBhbmQgTWF1cml0aXVzIGxlYWQgaGVyZSB3aXRoIG1ham9yaXR5IG9mIG90aGVycyBmYWxsaW5nIGJlbG93IHRoZSBsZXZlbHMgb2YgdGhlc2UgY291bnRyaWVzLgoKIyMgRXVyb3BlIGFuZCBDZW50cnRhbCBBc2lhCiAgCmBgYHtyIEV1cm9wZSBJcnJpZ2F0ZWQgVG90YWxzIEdyYXBoLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpwaXJyRVUgPC0KICBnZ3Bsb3QoZGF0YSA9IHN1YnNldChhZWksIHNpeF9yZWdpb25zID09ICJldXJvcGVfY2VudHJhbF9hc2lhIiksIAogICAgICAgICBtYXBwaW5nID0gYWVzKHg9eWVhciwgeT0gaXJycGVyYywgY29sb3IgPSBjb3VudHJ5KSkgKwogIGdlb21fbGluZSgpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoKSArCiAgdGhlbWUocGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSkgCgojcnVuIHRoaXMgc2VwYXJhdGVseSwgb3RoZXJ3aXNlIHRoZSBwbG90bHkgcGFydCBkb2Vzbid0IHdvcmsuCmdncGxvdGx5KHBpcnJFVSkKYGBgCiAgCkV1cm9wZSBjb250YWlucyBzb21lIGNvdW50cmllcyB0aGF0IHJlYWNoIGhpZ2hlciBwZXJjZW50YWdlcyBvZiBpcnJpZ2F0ZWQgYXJlYS4gQ291bnRyaWVzIHN1Y2ggYXMgdGhlIE5ldGhlcmxhbmRzLCBSb21hbmlhLCBBbGJhbmlhLCBhbmQgQXplcmJhaWphbiBoYXZlIHJlYWNoZWQgcGVha3MgaW4gdGhlIHBhc3QgKHJvdWdobHkgMTAtMTUlIGlycmlnYXRlZCBhcmVhKSBidXQgc2VlbSB0byBiZSBpbiBhIGRlY2xpbmUgdG93YXJkcyB0aGUgZW5kIG91ciBzdHVkeSBwZXJpb2QuIE90aGVyIGNvdW50cmllcyBzdWNoIGFzIEl0YWx5IGFuZCBEZW5tYXJrIGhhdmUgaGFkIG1vcmUgc3RhYmxlIHJpc2VzIHdpdGggbGVzcyBkb3duIHR1cm4gdG93YXJkLiBVbmV4cGVjdGVkbHksIFJ1c3NpYSBoYXMgYSB2ZXJ5IGxvdyBwZXJjZW50YWdlIG9mIGlycmlnYXRlZCBhcmVhLCBob3dldmVyIGF0IHRoaXMgcG9pbnQsIHRoZSBhc3N1bXB0aW9uIGlzIHRoYXQgZWl0aGVyIFJ1c3NpYSdzIGVub3Jtb3VzIHNpemUgY2FuY2VscyBvdXQgaXRzIGlycmlnYXRlZCBhcmVhLCBvciB0aGF0IFJ1c3NpYSByZWNlaXZlcyBlbm91Z2ggcHJlY2lwaXRhdGlvbiBmb3IgdGhlIGNyb3BzIGl0IGdyb3dzIHRoYXQgaXJyaWdhdGlvbiBpcyBub3QgbmVjZXNzYXJ5LiBGdXJ0aGVyIGFuYWx5c2lzIHNob3VsZCByZXZlYWwgdGhpcy4gIAoKIyMgQW1lcmljYXMKCmBgYHtyIEFtZXJpY2FzIElycmlnYXRlZCBUb3RhbHMgR3JhcGgsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnBpcnJBTSA8LQogIGdncGxvdChkYXRhID0gc3Vic2V0KGFlaSwgc2l4X3JlZ2lvbnMgPT0gImFtZXJpY2EiKSwgCiAgICAgICAgIG1hcHBpbmcgPSBhZXMoeD15ZWFyLCB5PSBpcnJwZXJjLCBjb2xvciA9IGNvdW50cnkpKSArCiAgZ2VvbV9saW5lKCkgKwogIHNjYWxlX3hfY29udGludW91cygpICsKICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpKSAKCiNydW4gdGhpcyBzZXBhcmF0ZWx5LCBvdGhlcndpc2UgdGhlIHBsb3RseSBwYXJ0IGRvZXNuJ3Qgd29yay4KZ2dwbG90bHkocGlyckFNKQpgYGAKICAKSW4gdGhlIEFtZXJpY2FzLCB0aGUgJSBvZiBhcmVhIGlycmlnYXRlZCBieSBjb3VudHJpZXMgaXMgbG93ZXIgdGhhbiBBc2lhIG9yIEV1cm9wZS4gUGVha3MgaGVyZSBhcmUgQ3ViYSBhbmQgdGhlIERvbWluaWNhbiBSZXB1YmxpYyBhdCBhcm91bmQgcm91Z2hseSA2LTglIG9mIHRoZWlyIHRvdGFsIGNvdW50cmllcyBiZWluZyBpcnJpZ2F0ZWQuIFRoZXJlIGFyZSBzb21lIGlzbGFuZHMgKEJhcmJhZG9zIGFuZCBTdC4gTHVjaWEpIHRoYXQgaGF2ZSBzaGFycCBpbmNyZWFzZXMgaW4gaXJyaWdhdGlvbiBmcmFjdGlvbiwgYnV0IHRoaXMgY291bGQgYmUgYmVjYXVzZSB0aGV5IGFyZSBpc2xhbmRzIGFuZCBhbnkgaXJyaWdhdGlvbiBhdCBhbGwgd291bGQgaW5kdWNlIHRoZSByYXRpb24gb2YgaXJyaWdhdGVkIGxhbmQgdG8gdG90YWwgbGFuZCBzcGlrZS4gQ291bnRpZXMgdGhhdCBoYXZlIGV4cGVyaWVuY2VkIGEgc3RlYWR5IGluY3JlYXNlLCBidXQgYXJlIG5vdCB0aGUgbGVhZGVycyBpbiBvdmVyYWxsIGlycmlnYXRpb24gZnJhY3Rpb24gYXJlIGNvdW50cmllcyB0aGF0IGFyZSBiaWcgYW5kIHByb2R1Y2UgYSBsb3Qgb2YgcHJvZHVjZSAoVVNBLCBNZXhpY28sIENoaWxlKSBUaGUgZ2VuZXJhbCB0cmVuZHMgb2YgaXJyaWdhdGlvbiBpbmNyZWFzZSBzZWVtIHRvIGJlIHVwd2FyZCB3aXRoIHBlcmhhcHMgYSBzbGlnaHQgbGV2ZWxpbmcgb2ZmIHRvd2FyZCB0aGUgZW5kIG9mIHRoZSBzdHVkeSBwZXJpb2QgKGZvciBzb21lIGNvdW50cmllcykgYnV0IGxhY2tpbmcgdGhlIGRpc3RpbmN0IGRvd250dXJuIHRoYXQgaXMgc2VlbiBpbiBFdXJvcGUuICAgCiAgCiMjIEVhc3QgQXNpYSBhbmQgT2NlYW5pYQoKYGBge3IgRWFzdCBBc2lhIGFuZCBPY2VhbmlhIElycmlnYXRlZCBUb3RhbHMgR3JhcGgsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnBpcnJFQXNpYSA8LSAKICBnZ3Bsb3QoZGF0YSA9IHN1YnNldChhZWksIHNpeF9yZWdpb25zID09ICJlYXN0X2FzaWFfcGFjaWZpYyIpLCAKICAgICAgICAgbWFwcGluZyA9IGFlcyh4PXllYXIsIHk9IGlycnBlcmMsIGNvbG9yID0gY291bnRyeSkpICsKICBnZW9tX2xpbmUoKSArCiAgc2NhbGVfeF9jb250aW51b3VzKCkgKwogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCkpIAoKI3J1biB0aGlzIHNlcGFyYXRlbHksIG90aGVyd2lzZSB0aGUgcGxvdGx5IHBhcnQgZG9lc24ndCB3b3JrLgpnZ3Bsb3RseShwaXJyRUFzaWEpCmBgYAogIApUaGUgRWFzdCBBc2lhbiBjb3VudHJpZXMgYXJlIHF1aXRlIGhpZ2ggaW4gJSBvZiBpcnJpZ2F0ZWQgYXJlYSwgd2hlbiBjb21wYXJlZCB0byB0aGUgQW1lcmljYXMgb3IgQWZyaWNhLiBUaGUgZm91ciBjb3VudHJpZXMgdGhhdCByZWFjaCB1cHdhcmRzIG9mIChyb3VnaGx5KSAxMCUgb3IgbW9yZSBvZiB0aGVpciB0b3RhbCBhcmVhIGlycmlnYXRlZCB0b3dhcmQgdGhlIGVuZCBvZiB0aGUgc3R1ZHkgcGVyaW9kIGFyZSBWaWV0bmFtLCBOb3J0aCBLb3JlYSwgU291dGggS29yZWEsIGFuZCBUaGFpbGFuZC4gT3RoZXIgY291bnRyaWVzIHRoYXQgaGF2ZSBoaWdoIGlycmZyYWNzIGFyZSBDaGluYSwgSmFwYW4gYW5kIHRoZSBQaGlsaXBwaW5lcy4gSXQgaXMgZXhwZWN0ZWQgdGhhdCBmb3IgdGhpcyByZWdpb24gdGhlIGlycmlnYXRpb24gZnJhY3Rpb24gd291bGQgYmUgaGlnaCBkdWUgdG8gdGhlIGFtb3VudCBvZiByaWNlIHByb2R1Y2VkLiAKCk9jZWFuaWEsIGR1ZSB0byBpdHMgbGFyZ2UgYW1vdW50IG9mIGlzbGFuZHMsIGRvZXMgbm90IGhhdmUgYSBsb3Qgb2YgaXJyaWdhdGlvbiwgbWFqb3JpdHkgb2YgY291bnRyaWVzIGhhdmUgMCUgaXJyaWdhdGlvbi4gTmV3IFplYWxhbmQgKGFyb3VuZCAyJSkgYW5kIEF1c3RyYWxpYSAobGVzcyB0aGFuIDElKSBoYXZlIHNvbWUgaXJyaWdhdGlvbi4gQWx0aG91Z2ggdGhpcyBjb3VsZCBoYXZlIGEgbXVsdGl0dWRlIG9mIHJlYXNvbnMgd2h5IGlycmlnYXRpb24gaXMgc28gbG93IGhlcmUsIHJlZ2FyZGxlc3Mgb2YgdGhlIGZhY3QgdGhhdCBBdXN0cmFsaWEgYW5kIE5ldyBaZWFsYW5kIGFyZSB2ZXJ5IHBvcHVsb3VzIGNvdW50cmllcyB3aXRoIG1vdXRocyB0byBmZWVkLiBBdXN0cmFsaWEgaXMgdmVyeSBsYXJnZSBhbmQgcGVyaGFwcyBpdHMgZW5vcm1pdHkgY2FuY2VscyBvdXQgdGhlIGlycmlnYXRlZCBsYW5kIGl0IGRvZXMgaGF2ZS4gCiAgCiMjIFNvdXRoIEFzaWEKYGBge3IgU291dGggQXNpYSBJcnJpZ2F0ZWQgVG90YWxzIEdyYXBoLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpwaXJyU0FzaWEgPC0KICBnZ3Bsb3QoZGF0YSA9IHN1YnNldChhZWksIHNpeF9yZWdpb25zID09ICJzb3V0aF9hc2lhIiksIAogICAgICAgICBtYXBwaW5nID0gYWVzKHg9eWVhciwgeT0gaXJycGVyYywgY29sb3IgPSBjb3VudHJ5KSkgKwogIGdlb21fbGluZSgpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoKSArCiAgdGhlbWUocGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSkgCgojcnVuIHRoaXMgc2VwYXJhdGVseSwgb3RoZXJ3aXNlIHRoZSBwbG90bHkgcGFydCBkb2Vzbid0IHdvcmsuCmdncGxvdGx5KHBpcnJTQXNpYSkKYGBgClZlcnkgZmV3IGNvdW50cmllcyBoZXJlLCBjb3VudHJpZXMgaW4gdGhpcyBhcmVhIGFyZSBsYXJnZS4gVmVyeSBoaWdoIGxldmVscyBvZiBpcnJpZ2F0aW9uIGhlcmUgY29taW5nIGZyb20gbW9zdCBjb3VudHJpZXMuIEJhbmdsYWRlc2gsIFBha2lzdGFuLCBhbmQgSW5kaWEgYXJlIGhlYXZpbHkgaXJyaWdhdGVkIGNvbXBhcmVkIHRvIHRoZWlyIGxhbmQgYXJlYS4gCgoKIyMgTWlkZGxlIEVhc3QgYW5kIE5vcnRoIEFmcmljYQpgYGB7ciBNaWRkbGUgRWFzdCBhbmQgTm9ydGggQWZyaWNhIElycmlnYXRlZCBUb3RhbHMgR3JhcGgsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnBpcnJNRSA8LQogIGdncGxvdChkYXRhID0gc3Vic2V0KGFlaSwgc2l4X3JlZ2lvbnMgPT0gIm1pZGRsZV9lYXN0X25vcnRoX2FmcmljYSIpLCAKICAgICAgICAgbWFwcGluZyA9IGFlcyh4PXllYXIsIHk9IGlycnBlcmMsIGNvbG9yID0gY291bnRyeSkpICsKICBnZW9tX2xpbmUoKSArCiAgc2NhbGVfeF9jb250aW51b3VzKCkgKwogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCkpIAoKI3J1biB0aGlzIHNlcGFyYXRlbHksIG90aGVyd2lzZSB0aGUgcGxvdGx5IHBhcnQgZG9lc24ndCB3b3JrLgpnZ3Bsb3RseShwaXJyTUUpCmBgYAoKSXJyaWdhdGlvbiBpcyBhbHNvIHByZXZhbGVudCBoZXJlIChidXQgbm90IGFzIG11Y2ggYXMgaW4gc291dGggQXNpYSkuIFRoZXNlIGNvdW50cmllcyBhcmUgZHJ5IGFuZCB0aGVyZWZvcmUgd291bGQgbmVlZCBpcnJpZ2F0aW9uIHRvIGhhdmUgZG9tZXN0aWMgZm9vZCBzdXBwbGllcy4gTGViYW5vbiwgSXJhcSBhbmQgSXNyYWVsIGxlYWQgaGVyZS4gT2lsIHByb2R1Y2luZyBjb3VudHJpZXMgaGF2ZSBsaXR0bGUgaXJyaWdhdGlvbiwgdGhleSBhcmUgZHJ5IGFuZCB0aGVpciBHRFAgaXMgaGlnaCwgcGVyaGFwcyBpbXBvcnRhdGlvbiBpcyB0aGUgZWFzaWVzdCBvcHRpb24gZm9yIHRoZW0/CgoqKioKCk92ZXJhbGwsIHRoaXMgbWlnaHQgYmUgYSBnb29kIG92ZXJ2aWV3IG9mIHdoYXQgaXJycGVyYyBsb29rcyBsaWtlIGZvciBlYWNoIHJlZ2lvbi4gCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9VFJVRX0KCnRoZW1lX3NldCh0aGVtZV9taW5pbWFsKCkpCgpnZ3Bsb3Qoc3Vic2V0KGFlaSwgIWlzLm5hKGlycnBlcmMpKSwKICAgICAgIGFlcyh4PXNpeF9yZWdpb25zLCB5PWlycnBlcmMsIGZpbGw9c2l4X3JlZ2lvbnMpKSArIAogIGdlb21fYm94cGxvdChzaG93LmxlZ2VuZCA9IEZBTFNFKSAgKyAKICBjb29yZF9mbGlwKCkgKwogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkKYGBgCgoqKiogCgojIFJlZmVyZW5jZXMK